{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#default_exp torch_core"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "from fastai.imports import *\n",
    "from fastai.torch_imports import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "_all_ = ['progress_bar','master_bar']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if torch.cuda.is_available():\n",
    "    if torch.cuda.current_device()==0:\n",
    "        def_gpu = int(os.environ.get('DEFAULT_GPU') or 0)\n",
    "        if torch.cuda.device_count()>=def_gpu: torch.cuda.set_device(def_gpu)\n",
    "    torch.backends.cudnn.benchmark = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Torch Core\n",
    "\n",
    "> Basic pytorch functions used in the fastai library"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Arrays and show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.subplots, keep=True)\n",
    "def subplots(nrows=1, ncols=1, figsize=None, imsize=3, add_vert=0, **kwargs):\n",
    "    if figsize is None: figsize=(ncols*imsize, nrows*imsize+add_vert)\n",
    "    fig,ax = plt.subplots(nrows, ncols, figsize=figsize, **kwargs)\n",
    "    if nrows*ncols==1: ax = array([ax])\n",
    "    return fig,ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "_,axs = subplots()\n",
    "test_eq(axs.shape,[1])\n",
    "plt.close()\n",
    "_,axs = subplots(2,3)\n",
    "test_eq(axs.shape,[2,3])\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fig_bounds(x):\n",
    "    r = x//32\n",
    "    return min(5, max(1,r))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(plt.Axes.imshow, keep=True, but=['shape', 'imlim'])\n",
    "def show_image(im, ax=None, figsize=None, title=None, ctx=None, **kwargs):\n",
    "    \"Show a PIL or PyTorch image on `ax`.\"\n",
    "    # Handle pytorch axis order\n",
    "    if hasattrs(im, ('data','cpu','permute')):\n",
    "        im = im.data.cpu()\n",
    "        if im.shape[0]<5: im=im.permute(1,2,0)\n",
    "    elif not isinstance(im,np.ndarray): im=array(im)\n",
    "    # Handle 1-channel images\n",
    "    if im.shape[-1]==1: im=im[...,0]\n",
    "\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if figsize is None: figsize = (_fig_bounds(im.shape[0]), _fig_bounds(im.shape[1]))\n",
    "    if ax is None: _,ax = plt.subplots(figsize=figsize)\n",
    "    ax.imshow(im, **kwargs)\n",
    "    if title is not None: ax.set_title(title)\n",
    "    ax.axis('off')\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`show_image` can show PIL images..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 72x72 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im = Image.open(TEST_IMAGE_BW)\n",
    "ax = show_image(im, cmap=\"Greys\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with standard `CHW` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im2 = np.array(Image.open(TEST_IMAGE))\n",
    "ax = show_image(im2, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and color images with `HWC` dim order..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "im3 = torch.as_tensor(im2).permute(2,0,1)\n",
    "ax = show_image(im3, figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(show_image, keep=True)\n",
    "def show_titled_image(o, **kwargs):\n",
    "    \"Call `show_image` destructuring `o` to `(img,title)`\"\n",
    "    show_image(o[0], title=str(o[1]), **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_titled_image((im3,'A puppy'), figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@delegates(subplots)\n",
    "def show_images(ims, nrows=1, ncols=None, titles=None, **kwargs):\n",
    "    \"Show all images `ims` as subplots with `rows` using `titles`\"\n",
    "    if ncols is None: ncols = int(math.ceil(len(ims)/nrows))\n",
    "    if titles is None: titles = [None]*len(ims)\n",
    "    axs = subplots(nrows, ncols, **kwargs)[1].flat\n",
    "    for im,t,ax in zip(ims, titles, axs): show_image(im, ax=ax, title=t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAO0AAACDCAYAAABhs5ylAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOy9edBl6V3f93nWs97lXfrtnp59kWYkoUErSIBDoCAmOEthYgpIIMQh4NjB/BG7UlmqkmBT8R5CKC9FHBsnduLEKWMwTpUhDiAhFgmtCKFtNGuvb7/ve7ezPVv+OHda02P1ZCQkzbS4n6quOk+fe849t0//nuW3fB+RUmLHjh13DvKVfoAdO3Z8fuyMdseOO4yd0e7YcYexM9odO+4wdka7Y8cdxs5od+y4w/gDa7RCiCeFEN/ySj/Hjh2fL39gjXbHjjuVndH+PhFC6Ff6GXb8weJVZ7TbaeufEUJ8WAixEEL8QyFELoT4ASHEu1/02SSEeGR7/HeFEH9dCPF/CyHWQohfE0JcEEL8hBDiVAjxe0KIN7/o694uhPjd7fm/I4TIX3Dvf0MI8UEhxJkQ4j1CiMdf9Iz/mRDiw8BmZ7g7vpy86ox2y3cB3wY8CDwO/MDncd1/BRwCPfDrwPu37X8E/LUXff7fBf4w8DDw2u21CCHeAvzPwA8DB8DfAn5OCJG94NrvAf4IME8p+c/r1+3Y8fvg1Wq0P5lSupRSOgF+HnjTy7zuH6eUfjul1AH/GOhSSn8vpRSAfwi8eKT9qZTSM9vv+XFGQwT4j4C/lVL6zZRSSCn9DGMn8I4XPeMzKaX2C/yNO3Z8QbxajfbKC44boH6Z1119wXH7Odovvs8zLzh+Cri4Pb4f+E+3U+MzIcQZcO8Lzr/42h07vmzcSWuxDVA+3xBCXPgi3PPeFxzfB1zaHj8D/HhK6cdf4tpdedSOV4RX60j7ufgQ8AYhxJu2DqP/5otwzz8lhLhHCLEP/BeMU2iAnwb+hBDia8VIJYT4I0KIyRfhO3fs+H1xxxhtSukTwI8BvwR8Enj3S1/xsvgHwD8Hntj++fPb73of47r2p4BT4FO8fGfYjh1fUsSuCH7HjjuLO2ak3bFjx8jOaHfsuMPYGe2OHXcYO6PdseMO4yXjtN8q/9jOS/Uq5Bfj/yle6WfY8cqxG2l37LjD2Bntjh13GDuj3bHjDmNntDt23GHsjHbHq4KtsMB//mJRgpcpfvA3hRC/KIRYCSF+RQhx/4s++6eFEE8IIY6FEH9ZCCGFEJkQ4kQI8cYXfPZICNEKIc59+X7558/OaHe8mvicogQv87o/xyh28EHg77/o/HcAbwPeAvzbwB9PKfXA/w78ey/43PcAv5RSuv6F/oAvBzuj3fFq4naiBP9//EJK6Ve3hvhfAu8UQryw7PIvppROUkpPAz/xgvv+DPC9Qojn7eD7gP/l9/8zvrTsjHbHq4nbiRK87OtSSmvghNsLFty8b0rpNxnrtL9RCPEY8Ajwc5//Y395uZOK4Hd85fO5RAlejvjBvS84XwP7fFbQ4PnzH33RfZ/nZxinyFeAf7SVKnpVsxtpd7ya+FyiBC9H/ODbhRDfIISwjGvb30wpvXB0/bNCiL3tlPlH+azYAYzT4e9gNNy/98X/SV98dka749XEvyRK8DLFD/4B8F8zTovfyuiYeiH/BPhtRifVLwB/+/kTKaVnGRU7E/CuL+Jv+ZKxmx7veDXx3pTSf/fiv9xqdb1Qr+t/fdFHjlNKf+Il7vvPUko/+RLnnwZ+I90hihA7o93xBxohxAPAH+Vfltd91bKbHu/4A4sQ4s8BvwP85ZTSZ17p53m5vKRG1KuhNO/s+9958/jgP3jqlnM//9p/ektbic/2QV/9l/7kref6W3/Kub/x61+sR/yysyvN+4PNbqTdseMOY7em3cG7fvW3UrM5JfgBW8xYrFssjoceeQTvHaenpwghqOspWgu6bqDrWvq+pywnTGcT6rrEDZ7f/djHOD6+SpblpAgf+dD7+eX/95e4duUKeV5hjaXIMu46f8R3fPf38paveSeXnnuWvJrywL0XmUwmrNYrhr4hpURelAghgETfO5wbiDHSdy15XlCWFVVdUBQV165eIyVBCI6TG1fQJqOuaqrJlKIokFKyWi3Q2uC9IyVB13vyzLBebSiKnITg+PgqQiiKvKAsC05Ob7A3P2Cz2TAMnphgOq2ZzWqkEJyennK2WGBMhpIQQuT09BTvA1luUVLTDQ5jMpbrFd4N1PWEPCvwrkMKgZCCK5evoZSgrmsuX7nGD/3Q93/OGdUrbrRC3/oIl/7019zS/ic/+pduHt+ji1vOxRfdK6Zw8/h9f/Z/vOWce8E5gDff86M3jx/+iU/dci5cf1Wnnn7R6fuewQ1obUgpMpvURNeSUqIsK85OT0kI+r7Fe40xFmMUR0fnsJkBBH3XMwwD9997HxfOn0dKsFnGY4+9nsff9HZ+5u/+NE988uMoqej7juMbp7zrX/w/7B0ccP8D97O3fzAayMkJbdsymVRoo+i6hqKoiFFgtEYrRRKSoqgQJKRW5HnOYnG2NW6B1oZzR3eT5ZZia/TODYQQUVKw2WwQQiGEwOjRLlabDVIJjC05d+4869WamAKbZkOeF6zWC/KsJMsss9kMpRSDGzg5PWMYHJN6gnOOvh+o6pLJdMpmsyazBUIkEgmlYK/OaToQwMliQ5kJDvf36LqWosgYBs+maYhhuO372k2Pd5Dnlr3pjKIo6LsOHyCInARkWYbSEq0UeVGQFxl1XTHfm5MXOX3f0zQdzkecc4ToODp/jvl8j7IsKauC17z2Uf7Yd30vDzz0ICH0xJhohp5nnnmO9/7auzg4OKQsCxaLBYPrKcucoe8QQlLXM7zrkXI0xohkvW554ukrnC4bJlU9djqDxzmP8x02y5jOpkynMwC8HxACgo+AoipLjJZkmcFaCyTmsxpjLELAMAzU9dg22lLkBUVRAomqKslyS9OuWSwWSKUR0pBSwticrCjwIVGVJdYayqoEodBq7KyUNkzqGSkJ7rlwwIP334vSktVqic0MNrP0vaOup7d9X6/4SLvjlSfLLf1mICXBbD7FDY48zwje0w89k+mEth2YTGqkHP/zt+0ACGJIJMCHSJaVHN+4wnQ2w1iDcx5jJFWV89a3vhVrNX/zp36C5dkCmSzLZsPHP/YxPvrhD/Dgax5Da40xBiElPiaGwWEzRVXPaJo1bhho255nnnqS3/ud32Fvb8aTH58hheDivfdTTmbUVUlZ5mitCMEjpSAEQQgRhEBpSZZZKlnRNC0pQYyRvb09+t6PHY8PiEyg5HY0NpZ6UrJcLHHecenSJYSQKCVIMWCMQCvN2WpFkeWsV6djxzHd4/j4KvsH5/GuRynN4Hrmsynz/TlD13Pt2jWc89gsI/hEtZfRtC3rTXPb97Uz2h24weOiQCmIIRCioyjnVHVJipGiKOn7geVygRscUlnyPMO5npQidVVjDFy9eoVaQ3ADVVUh5TiRk7LHGM0bH38Tb3/HO/nFf/bz9H1DNzhiCPz9v/M/8YP/yY/ymkcfo2kH+s0JQ5DMZlNW64ZOAcnzwfe9l/e++5e59PSzDG0LKaG0xmYFs709ji5e4M3v/DoefOS1zGYzsrwghAQIYox478nznNOTM2bzGXme4X0khICUEmMU3vdYa4ghMJ3WGDuOxs4NCClYr5ZIaRACQBJJSBFJRPZmU5q2J8sqlNIoYzg6d54rVy9TV1O6bs3B4Tnm8znXrl1js2kJ3qO1ROmCZRMJQnPh6JDPPH3ptu/rFQ/56HvuvqX98M9eu6X9V+/6jS/1I/Ap19/S/o//1I/e0s5+4b1f8mf4fPhih3w+8IGPJEjkmSUlcEOHNhofAt6PvoAYBXmWI6Xkxskx1mhiDNSTCRJBiAlt9DhKJT86f8qSYXDE6Om6gb4PfPzjH+Ov/oUf48bxCR5BkWUYEXn7297C9/zAf8g99z+CEAmRoOs7+rblE7/7YT75kfdz/Zln6TYNQkgQkgQMzhMioDVCKoqq4ujCEW9401fz2ONv4sJd96KNIsVA3w8Uec5602CMHjuF1RqlNCklpFIIIl3XobXZdjyC9XrNarUc/w1yS9tsUDonBE/btPjgqKuaLM/puoEQPM1mTQKUBB8ETbNmPptRVTXHN25wenpCkecYm+OdQxtLPzhSCkzqmvW64du+7ZtenY6oHa88MQ64wTF0DYmEcwFrc2xmyLJqO83U2MzQdR1WepLrqOdHRO+JySN1hjE5l577DJNJRZI9Umqy3LJedxRljlKOhx96iEde+yhXLv8yEUFSkiAlH/3Qh/m5/+N/47u+/49zdO6Ap596it/7yId48mMfZnHtmE3b450jxoiSEikEymiMMlijEFoRkXRtx5VL1zg7fRcf/+jHeN3jj/Pmt72dcxcuIIRAG8V8PsE5j/cBrTV9P5BlGdZqlJTkeYHWmqbZsFickRJobTDa4oMjywu6thv/XkEYHIlE1w2s1htSHNDakoQmRc/+XoWSgrPFGdePbyBF4vDggMELgu9ACPLcoJTi5PjK6GB7iW55Z7Q7CEEREMzqAqXh2tVjBjcgRMQNHiECUVj6oWNwjqLaY7NeIE2J0o5N46BdAYrzFy6glURqg0+CShvKsqDrerTW5EXGO975Tj70wQ9w4/iETrRIqSBF3vsbv0kcel77utfz1Mc+wvHVq/S9o+l6Vm1HAiprSSSs0igXEIVAeY9JgcLmzKuaIYJznhvXT/mtd7+Hs+Njvv07/x3OXzjPOLNMFIWgaRq0VvR9QspEDJ7g09agHWdnZ1RVTVkWN6f6FkNKo7MqhEReFNR1jTKW1bolzwzOgRCR2bRGaUUMHiHHsFVZlXg3IJWk0JrTlaP3Cd07Tk6uQZQoZeAlZsCvuNH6Z5+7pf1LP/t1t7TXP/wrN49rmd1y7mpob2n/SntTGoh7zY1bzr0zuzXk80IeMbfe96l/89Zu7rW/cNtLvyJo2h4pIoiCLMuxVlMUFc4PrFdLhNQMrsHmBVVZkJcTbJaTpEELwbRWtOsWISQnyyVCSQ739hmGHu8tUmquXXuWssgAyRu/+m088ujrOTl5F71zGBVJWnJuWrO6con3PP0UvfNsupZ+8PjgEQiElLjgUVKipBg7BymQAmKIRD/guzW5zZgUGVGCBz7zqc/wiz//c3zTv/5tTGdzhJDEGNmsNxhrMcbifUSI0aBBYoxlb2/OerVBINFaE0JkdLslrM1IMaLNGCaTUlKVGUbXhBjp+5bptObatWus1xuUUuztHXBycoN6Mif4nhAdMgUqO4ayMltCirih267FPzevuNHueOXJs3GKGVPaOlgEXdfhw0BVT7BZwTA46qpCa4kxGh81bdvQuQarFUW1h4+J5WrJhaNzzGcVWkmapmUYHAf7+wTfIRgdPl//DX+I3/voh9gs1+Rac/f+HCPh+OQUHxPtMNA5jxKg1Th1jDHQ9ANaSkiCqtCsmharLZkxyCiJAVLv8H5JOamxImGN5bknnuK33/Vu3vIN38h8b06WZYSQWG0aDvfLrZc5kBKkGDFW45yg2XTbZUJOu3V+pZSIKWLzEu8cIQqc83RdgxCgtUJrzXOXLtO1Gw4Pz9MPHTFE5vN9Nk1DlleoNKCkoO0HBgd1PR1H+NMbTKd7t31fuzjtDhZnN/Ah0vcOISRSSbSxVPUMIcaRLLMW7wdOT09JMeD7hhQGWgdPXu9Ytx2zacmbvur13H/vPcTgWS1XDL1DKUVZVVTVBCkSmVE8+ujreONXv5mqzLj/3AFaSK6fLth0HW3X0Q1udIRF6ENkiGmMdxpLnuWEBIP3aG3p3EDjPU3fQRo9xUhFihC6Frc6QfuGZz/5MZ5+4hMkIlKO68giz+gHxzB4QkyE7VRWynF0tTYjpUTf91hjEXIca7XJgUhMgUhisV6jtSCzGq0NXe/GOG09B6XQWY0tarQtsPmE9WoBGJwL5DZHawiJMYurnnFwsH/b97UbaXegQosREWWL0eFiNN5FNt1AmWmsMfgQ8W6AFFmvF2htKcuSLIeyDMynBVornHMsFqfjiJcgSY2IkaZpKcsCbXNs5pjPp3zt27+W7vIzbNYN664npYASgt4nXIhIASFGYkyjt1iATJHcjE6jtm/pAmglMTFh8gylNEEItDIEBEZpUkgsj68xtGuuP/Vp1NvezvMLIGskQgiUGo1UiHE9HEJEKY2xFogYoxlCwtqCTedpu4iOLTEMKFsxdA251EgJ0haQEsEPNItTrL2HiKHregafQGVok5NSRGlDCI6m2SBNRV5XHNx7NyneQdPje//8e25pf538MzePh/1bExfve8PlW9r2Wz9bBXTjB7/rlnO//t/+1Mt+hm9580dvaV968LNrZf+Zp1788Tue2dEDqEwBgRA8xhiCd8zriizPsNYS2zVCCMqyQhtNUZRYo5FqnFYOQ0/btmRZjtEZzbBhtVqTFxW973BDDxyhpCbGxPL0Op/88Ps5Waxo+oEQAkYJusTWSAURORpXSsTg0NogEPgYSXi0zRAJCmtxITIEgUyglCLEhEsCpRTWaLS1eO/5xPvfz/TgHG/7Q9+EVJK+aTDWYk1NCOOsQCk1hmuUQspx3SyEou0aTFVSZBatI0MjiEnQNx3KaKrJjGF5jO8F2hZIkXNltaSetdhcYKUnyxXaVpy4gbY9Y39vj7wouHrlCk27waiaFCLPXrrE448/9jnf16vOaHd8+YnB8dxnPo2tZuSZ3jpdGoSwKKWJCaTSTIoKaw3GGGIcDTX0YZxSywyb5wx9ixSgdEZVS6RM+Chou5bSebyAvnf8i3/6s3zkgx9i3fd0zpFiRAhFiBBiQmmFTAEQSCHRahzxM2MRWmOk5K6DGXuzOYtNw8liQwRSCGgtybSmMIoiz9BEhDZIKbHW8OQH34cWcM+jb+Dw3BExRtquQymBEGNBhNIao8fV45iTnZgU2fa3Cbp2g3MDSmconRBeEYaBbH5EigkhJevVmsPzFzFmDP0oKbFWIXVCxo75bMowOFbrNcZqLkzv4vLlSyg1dpq3Y2e0O0gkpvvnMDYnhEiWj+s4HzxaC7RWlMUESIQQWC43xDg6iLTOkAraQaBFQCtN27UYrZFSkaJH24LZnsINHSkJPvzb7+NDv/0BVl2PC4GUEgLY5nGM3mEhxxEX8CkiY0R6z35dcc+FIw7nUyRgrGVvNuXcvqPrO7QAo4AQCd2KTbdEKwlSMvjIpJ6S5Rkfec97+MSHf4eje+9j79wRk/195vv75GWJdwEpQYnZaNBNT15kWGsQQtD3PYtlgxs65vMMYmJ9fJm0f469esr168fkeY4PkbKakllDTBBkoKxqzs4WxOgoyxld15AYvepd1zGbTynyCc7fPtqxM9od5FmGKgtsliElaKWp65KyqnCuY7MZUEpR5CXGZlij6XuPsYamWeOdQyqNKfKtl1dsPdGRSCL4yKZpGIYBUuL9v/FuFutm6+QSuBAJKaCVQm3joYzZh4SYkEKQK8kb7r+Luw/3iBE2iyUoTQxryMrR+H1PlJIBiQthNBTnKMqSqCTeQ9j0sB5TFdPxGdcvX8UYi9SKyd4cqQ1Ds6awmnP33sfFhx/h8K57SCSyzALQ9T0pwcH+/piwkRccPfgYJjM0g0CaghA8k7pA6wznHF27oSxLpJT0/UCeFyyWKyCOnVuK2MzQd5H1Zknf9bd9X696o73vx95z23PqkQdvad++b/r8+Ov3/Oot7W+/7wdvHsuvwDUtItIPA4PrCcGPa0chaJoWoy15VpNllhASRo/hoWE4Gy8VmvVmRV1XW+9zQKtECgM2K+lij7EG40vWradZ3uDapUuEGEe7lIqQIKSE856BRGEzhBgdWbnRTMuCew/mzDPD8fEZm26gcZ46z8m0JgWBi4mua7HWYs3olQWBEppN76jqHJ86Fk2LFgIfAiFGrPNI1ZJlGc16w+AczekxlsDlj/8uT33oHA8+/tU8/JZ3cHTXPdjMUgFa55ACQiSkkCibMxbgReqqYrlcIHqPdJG+78e4sjWEECAFrFVsNh3W5jR9JPieIjP03YZucMxmB7d9Xa96o93xpce5gFIGJQUpaQKK6AeyzCCVJMaBrouEMHpRy2ockZVUWKvp2w1tu+Hw4ABjLAmB95GuX2CzDO8GumaDlpKTq1dYnhzjYyTAWCWU0pgcIRNKyq1BJYwSvPZojwfOH9CHxPWzBpcSTe+IKZLCmlRNEYMjSoVH0ncd1odtQlHCGoOKik3bMjhHAjrvCHGb7aU6CIG6LAhIkne4tsNFB8Ez+Mhm+WucXL7E67/+m7n/0ceo6pqiHOPGzo1rTz9EgnNMC0UIif35hBACXddCDOTVlLKoODk5IRGYTqdj0X1M9G5DXlWEKJlOFc31Yzab5W3f185odzCfzXHeEaNj041KCkqOJWxSSmJUbBpHnmkWqxV5YRHbYnaE4PyFC6zXS2yWY4wi+EhKARIMvWe5WrDZLLG2YnF6g2EYiDEhlEQoQQJiAoQYM5ykRGvFw4dz7j08YNn0XDpbMyYJCVrvKcxY2tcnzdFBxaZtSUojpSYw3kOK0bsrSMhth9O7sfxOK4UUAh/BOcdwNiAAkRJ1ltGuWoxIRGUIKJ751BPcuHaDK29+C49/wzcy2duHlOi7jrwomRSGYPW2dlcgpWJwY9ionk63yRuerusoiwwfIkhD1y7JTcLHgCDRO09grCq6HXe00YZPfWkE9P79J7/llrZ98vjmsf+SfOMrS9ttMMaSZTn7OqPv23H9ahQxQN91ZCqxacYEA+8Dmc1Zr9coPY7G4xJ0rFttuw6tJNpomuUSKSWZzVksjomhR0iJFJAQhJQI2yyj56fEIQTumdXcPZ9yfbXh2dMli7ajzkeHTUwJEXvWbQ8ukltDEGPVkdbZtg5WIpUgNxbfd0giSlp0No6mQ9dhlEYajQSEECyWSzKZsKJi0XVIMqYF+MExKMn60mU2q1+lWa14wzu+gYOL96DNWHccQiBGz7A5xRYTsrzaljT2eB+RSrLZbAg+UlUVXdsSQ2DT9lRFhhZj/rWTmnvO743ZV7fhjjbaHV8cvPOcHF9n/+CQoigxSoDYKlH4xKWnP83EOC4+8maGKOg6R13nrNcrlNKQIpN6wjCM1TJKSYwtcK5HaY3zA5v1kugHyqpEm7G4PKS0/c8eEQKM0sQYyYzm/KTkZNVw3PQs2oHBR3ofsHocQVEaW00IMXK62VCUE5LUKCVQNsMNAyIk+jSu00WSxO13FcYwpIT3ASkFSmm6vqPrGlo/0LYtIYF3A0Ip6skMFxJCSK5fOya+//20qxVf9a/8q9z94COI6EbFCg95fUgk0ffDqFShFEoqpJDbmUmk73qsHRUqqlJz+doJQiqmdYkg0Hctrl/d9n3tjHYHKQYyGYFRFC03ksBYHN8PPSF5tNbElJAwZv1IibF2DA35sYhcG7H1so7xWucHhqFjcXYGRIy1FJM9iiwnpQ0xjeOzVIrgPMRxxK2sJgbPceNY9I528PTe3SwM0CZDKUtRGE6OryGTRcVE8pG81MQUx8ICrendQN9s6BIoPXYWVVGMo7UaQ0u2LEhiLEhovGfVdaStsFvuoUChwpjm2PnIYrHm0tPPMv2932X/6DxZZtk0HdoY+iDJjSDimUwmnJ6eIKQmS4k8z5hMppDAeU8Ikn5w7E1LBuexGmKEsizZvMT72hntDmQ2R6cxytK7RMj3sLJndXoFIRQX736Q4AdW6w6tNdpY3OAwxrBaLEEIrK0wxtL1DavVGVZJFJH1coF3PbPZnOW6YbXpyTOLkoI+pNFwt+tZJBDG6fGmG1j3AwmJj4HcWvR2XZiUwQDr5RIXPFpkdM5RlpYUE77vMVIy9B3Jj0XpXf/89xqWbklVFAipyIwhz3LyLIcYuXz5GZrUcrJpaYaB3GjqakLCIFIgCmi6lmaz4sqnP8npY6/n4GAPW89B5bghkaUxc2/Un5IYrcmyUZXRuWGb+yzJiwxEJDNjIcbQO85WHVIElLp9WcDOaD8Hv/6R19zSfu1Tv/UKPcmXhyc+80nWy1Ne89DDlNUoTOb7ntNVQ11U1LXl5Nolyolnvn8B7z3B9+TluANlnuc413N6ekyMcYzjuoEUPPP5lHoy4+R0QdM6kpDkeY4UElK4KR8aPTeTKQBiDKQUWHU9gw8YrYiMWlR7WcbgPaer5ZgXHSH1LWWRY8SYLJJiRMRA2/d0fU/fNXg/kJsMJSWDGPOZdYrIPKeYzzF5MSo7nlxn8+yzdH2P0RqEwIeEIGG1QSqNGwI3jk+4/NSTHF68G20MQ7emzMpRrifP6bqOGBNKSW5cv8Jqccr5iw9g7bjW7bqGlOJYBjn09MOAUpYwNPTD7b0nO6PdAdFz8a6L2KwkywtiWBNS5J6Ld6O1pshz7rrvoTGv2GZ478f0u+WKED3L5RKtDXU9Yeg2eDfGH4XRuChZXD/h08+eknzP6vR0zGSSY2KFT5EQ42i8W0dU5yM+RqL3DMOAj+Pad/SvgjGGG4slm7ah6yQpBO46d4S1lk3bUGUZPnjatkEJ8MHTOY81hiF6+qbHO0tmMzSQtytskbN/eESZZ0zrCSddz6efewanLLaswAe0VGip6MIYrkoItDFAoh88/eAR0pFZg9aW5XI1FgVIjbEFe4c52miESGR5tg0Z9TTNBgSUkznu7AShFFK+WCD4s+yMdgePPPQQWitAUOQGIew2bPF8sryglBXr1ZKT01Occ1ibURQ5s9kB/TDQ9w0h9PjgMfmYjNF1ntVqMcrXaPAx8uSzV/Eqw0ggxe2fNBYFxISUgtZ5brRgpRylT2PE+4CIkTzL6IaexXrFptlQZhnBW3rXU4aSfuhpmzVaQNOMMVIXRwNYNRsEY8+Qgh+9zHZUqkiDgxApqglJCO4+f5FPX77CyXLJveeO0EKANiAVrl0TjUZpw/zceZS2tP3AZy6fcP9dB0zqfWJKbNYrlFJs2n4syTOKvmuxxpPEWMhQVyWrVYP3jnazQklJMZkTwslt39fOaHdQ16OcihAC0phE4ZzD+bHqZSwTExTFqF5oTUZVT0nsfPoAACAASURBVJAS+r5l6DsWp6dMJjPKar6t+hkNTSnDbFqxfwabFDnYq7jRHJIXz6C6sVAgpUhM4/pWb0ffRee4d5JhpWAQ4L3DGA0psW47lsslIiUgjoX5SuOdG508zrFoNhATXd8RxZgIEmPA+YBVElJktVljpBirmPxAih4hLVpJZnlGnWcMcZwJaCmQyoAcY8neO+r5lP2jI5TS5Dby+gcujHHtBL4fBcezfM6mG8g0KFUjlWZwDqUFRV6CYFxKxIBSCoCu61Aqu+37+oo12ovfd8dsgvaK07WbbZx09KBKqZBSMamrUStYKdzQU9UV3ocx9ug6hEj0XUvwgbysyIuKtm23ci4BuZWDWa9W2CwnJsX+fM7i9AbSZMByu3YdJVxiiohtOd4QIisXKYyi9ZF0M54bWW/WDENPlWcoIXHe4+OYwxu3qoouBNquw3kPpFHfeFuYEKMaw0wpkRvDbDLKyKSUSDEgUkKJRGU0p10/JkRMJ9vssDh2bjFw7uLdzOZzjLW4oaOocrz3WGu4fu0Em5VMJxWClrBVkMyzgq4XhABN29G1G9q2JXpHBPbmUzbrlra9fe7xTrliB86DsRVKFYQgcc5TFBUhQtePGT7D4FivN0ymU/LMMPQd69WSEDxKG6bTOf3Q48O4lUY/DGw2ay5deoaTG9fou44QEwlBWU7Q9ZzCjDEOkdJ2hjw6oqQQhBi50fRYKcjUaMhaCJz3tH23/dwYAmq7nsVyyardkFt7c2aQSKPecQiEGHDeEWKANI7uLgY2Xc+67xE2R1tL37X0bQsCqrxg8ANCQmYz2H6/kZLppObRN72FoppgrGFv/2BU/NBqdIKHQFHWCDmuYX3fINJYzmiMIcRRWjVGgdUWqTQX7rqIlGPMOM/tbd/XV+xIu+Pl44ZRU8majOXqjLqqWW+aMWtJKFJK1JOaFCMxjC6YlAJZVhKBqqzoh1G43BpN2o6YZ6eL7RTVsb9/jrZtyfOcLMs4ODqH9B1N9xS9c8SU8CHiQsAqRUITQ2TlAnWmaAfIlKAPkX5wZEahnndkbXdCiN6Tomdabte2/ShzKrYGLIRAC4kQEhciVqkxNCUkLgoWm45mvSB1DUZpJsUYBsq1RhnNZr3GD2Po6LG3vIm77r+fplkjhcRYg1aawFjSOBYGRGIM5EUBImG0GrdcCR5jNKvVElJEabAA0XPlyiXarmM2O3fb93VHG23zR7/2lvb/9T/8tZvHezJ/2ff51o9+5y3tR3/kg7e0X/FNer/UJEeeTwnBEUJC6Yyh92gZmM4PiCGQkqfvOmBM5E9Ieuc4ODjc7qA3UBQlzg3kMieEQD2pQCi6YeDGyQ2qqqaua9ppzdl0H6MNXdPQP3eZVdfTO0dmNImEloIhQOsCWkkmhd16lt3NMr7MGAJjKWHajs4pjKGeaZ7hXLl99oQPz2c/SaSQxDRmRs3qkvmkRkno2w2+7xk2G0RRMq8nGGNAgJKCMHSEoeG+197P13zLv0ZRFpydLqinU4SQo1rjNh85s6NQQPABiGQmIyGRIuHCQAgOayRKGmIK5NMJi8WKFMGajH7obvu67mij3fFFQiSi9xRlSVlM8DHhvacocmLo2ayX25FUUpYltpzg4hqQODfgQ8A5j1KOzBY07ZjPUxQ5TdPfDNM0qzPwPXleUk0mrDdLvM05tzcnnZyy6YdxTagMWkq8HAvihzCGhGqjaBFoqUlElNbj6C8UnQ9cOT3j9PQGU2tQ26KHWZEzeI/zEh/HXfNSHNe2y6YFIfjM8Sn758+4776HqLIC+o4YHCLLCTGSZdlo8L7l0cffwDd/53dz9/0P0LYtibFTabuBPDMAaGOo6yl93+OcQ0hBluVIoUhK0DuJlBFrC/p+wBhLjGPqY16UXDnrUO4Orqfd8aXn6PwFVmenNM1Yj1qWJaPSS2B5thgdKHmNUs9L0STKaoJzHX3fI4RCElgtzjjue85fuIeuHxPe9+YTpAgsl2u8iETXs7+/x/Xj6+RZzsV7HuAkLxiCh+UaFwIuJLQCIyVKyTF90AUm1pC208/cKNhOqQstODw8R/CBa1cv4boGoxSZsVR5jpGCBsjEqP+0appxq0rvmU2mLI+P2ZsdUE33GboWaXOC6xEEMm3GrC3X8egbX88f/oEfZv/oLozNR4ma7XoUPDazBD+uoWMcjVUg8N7TNCcYYynLiiLPaZoWIRTWZuR5xsnJCVJIsqrggbIkDLcvGNg5onagpMFkOV27JqUwbo7VN6yXC0IEk5Vok2Fshrb5tnxu3As2JUnT9Fy+cpVhGHABTs8WWJONSvyuG+tPi5x8Oufo7gfIi5y9vTkPPfIos4O7SFKTbE5WViSl8YAL4xow14pRqhTawSHFGNM1SpNbjdGa/fkBffCsBkc52+es7Wh6R+c9EsiVps4sWmqsVBipSHFM4Fj3A29/69fz8OvfgncDmRBcu3YFm2fMZqM0TWYUdZnxzn/rO9k7PH9TJP15UXPnBsoihwTLpqfrWpTWZHqrG2UtdT2h73vOzk5Zr1a07Zr1aoHSEu/DWKtsFUomqkx95W4LEn/o1s2fP5917AsZ/vaFW9qZe/ILfaQ7ktVqTVEWaLNitThBCEFeViipaTdrnI+jXGq2R0oCYy0nJzdGudIkEBIOz53DaEuM0LQbrl3vqOsKrcbtRCbTmrZt6buOlBLTyZTlcjnqIlUZy6pm0/UURUmMnnXfk9BUVmOkYoiBZvBkWt7UYk4xkILn4tF5Niny5NPPMZ/NOD25RmTcdDwzZnRsDT3ajhVCKS842TRMJzNe9/DruOux1+P3H+PC3pwjkVidXqUsS9q2Ae/IjeKxd7yTh173xq3wHEAahcq9Z7leUU1mFFU1Fgu4iJQG5GiIIQRONz11UaDlWGOstSFF6NqWpumQUjCd1OMO8k5xcrIrgt/xEkgJ3WbJpCwQmaFxEeci0uptamEgxchmvcRmGSebnuAjJzeuUk33mdQ1w6DJsoKmbQgp0jYN/TCMdbXa0jbr0chSIrM5MS5YblruvnCIO6hYtD3n9g9pNiuOT26wkorFesPUjiOWSIl28GR6NNjgPabIyLXi9OSYw8MDLuxXXLlxyqyuiWEUmVNSYqQkWosWEi0FtU203vP2N72Fr3rjO3huvcAsP83d9z3A4pknUBK01jjXQ4zUkwmPvfXt2+KGQJ7VtG2Hc6NYuqrUGOrarBnaDf3gmAFZXmw9x4pFO4zF91ZhM4MPmq5t6dZrBJIQA96P0+flakM5qW77vnZGu4PT4yv0LlAWBZBIQjOZzFkuF2NSAhqpLTazODfuM/P8WswaA3JUhOiG1RjPlIYoJGVRIKXAuQHnDG7o0Xpcv1VVwd13XSD4gWEY+KoIXbPh6pXLDH4UZRMC+uCZWM1mEIzJiGPOcuscgsgk03zq2ScxIvLg/hF70nB9cYLOcrRUTDJDJiFPCecDuZJoEkV1N0WKVCrw+vsexFQFi8UZH/jNX+W+C+cpjGQ6Kalyy2xvzrmL95DEqJioJwrP8/v4QFXXwFhWF7zDbKfNbdsx9APGGnKlkErifGC9WXB0dEQMjjzLGZxj6DtunJxgjaUuLYvNrmBgx0uglMIISzmZ0bajuoLzjiwr8JQU1ZwqA2s1pycNCjBGURQl601DEhmDixyfnnLX/hTXO6Qa47tZVpBSGOOV5QTvxmSMwlistZycnOF9S1kULBZr6tke5WTOlcvPsVmv8MsTLBHEqO8UUiLXmnXvubJY89DhHFLkQ088wceefobzhwcIBEYIZnXN0WxGbDd0MVKREENDkZdUhxdBap557knU1ec4Xa25evUSBE9VFsjkOTg6osoz9s6dIybIMosP24yrbjMK4CmFVGP9r5SJvYNzuGFgcB5jLNZmDMOAUnEUnjOaKjcM7YrlYkFV12htIGUMztH3PSkllLj9ovaONlrx0y8KQP/kF3afn/6L//0t7R85/ZFb2uafv+8Lu/GdgsoRKRKjYDrd4/TkeFR5SIKiyKlzQYqexdkKKTVDtya1Epvl7NmE9x0H8wmF1bi+YVrlJCHI82KbzzzmIAsxOl329w/RWnF84wY2M7Tt2AEcHO6jZGKxWJPnr0Ex8In3vxfRNWgBXYKTZtyNQApJN3iW3YBVChfGvX0uXbtGkVn6rmNalKM6o5WE1ZpcG3x0KJNTzvaQRUnXtpwuFly9eoWubTicVJS5QcaWowcfZlb9FufvvZd6MgUS5Xbv2LjdcLsucrwL2930JG55gjYWazTOjRtZd32LJGIV2935BE3rtnsGKYbBYa1mOp2xODsjCc1mc3vlip33eAfHx9e5dOlZ3DAWCMz35pA8bugRMZBnmhAcPiRiDChbctYnuiERkxzTD1PCWsVkNsMWFdoW5FlG26wAjRCKodsgSGiTceN0hRWRssiYTCccHB5y8a4LSKmYTWte8/D9KCFHNUMiRj1f0DDOm5Ucc6K7YUykYLsFpdiOUDEGRHBjCmJeMJ/O0RKkFGRlTVbkmMyileD0+lW61QJcT2klIjm8jyyuPMtrXvMgBxfvGaVo2pbNpmG1XuNDpKpKREpoJUjb9MhuGBUcY5QsF6dsNhussaPcjPNcv36dthtQSlMWOVppJpOx+EKKSL11Rq3WO7mZHS/B8uyYarI/FnIPjqqqScHjfU9MHiGgbVu838rDSJhXFU88e40LexVVrui7gcgo2FZVNXle0rYrhFAkxkJwkxWjZGjTkBlJigYVEkUxVrYkJPt7B0gpuHL5Euv1itWmxZYWI8d62wjj1FFIhBolY2aF5awbbtblBh8Icqyn9W2DqY9QWhOtwuUZxWw+hmxiQElBoQSLMGDUGNoZBo/Kai5fusH5C3eT11NiZKt/ZZBS3Nyvtu2bmwUWMYZtLnJG9B4pNd73DB4QBbN5TV7UuGFAackwyK2jL+J9RGtF6Af29/ZY6dub5h1ttLNfe/KW9jf/yJ+8efwX/srfuOXc12S3T0Z8rbk1Ofup77tV9vw1v/LZMqnU3z5T5U5lNj9k/9y9LJdLVuslR+cOOXd4wNVrn6asco6Pj4kRlJK0mw15keO6DY/cvYc1lvVmRW7H7CFtFFleIETADf22ymY7KnYNzvkx31ZBHwR6mw00uIDNSkwReO65p5FCUJUVPsZxn1opR0+0kjd30RMkXEz0PjCvchZNhxIStlPYUXhdowVgDImAFZaiLEEbJNAHR1UVTJuKMs84PHfIMHhclPQ+cnztlN/5rXdxcOG70SpA8iiTA4kYQUqFUnpbVDGgtWbYCrqNNcqaLBt3gV8uzsYdGqxEyAxEQsi03Ss3sFicstk0CJVRVfVt39dueryDerqHFJ6+72janmFwCKk4f+ECIYaxdhXo+2GUhomRYWhJwwYhElVZYWxGnufU1QSlBG2zRgqoyxxrzLhnbEz0vafpIghDVRQoKbly9Tnm0wnnDudsmjV5XqKznKKeUhUFm95jlRgzpORWrlWMxfmD8xyvW2ZFTpln1LkddZu3ucghRDItyZRAC7BZhs0yzNbo09DiNkuMElw4mo9i5klxthx1ll1KXH7mWYZ2NZYOivH3u6EftZ8HR9O2pBSBhNIahGRwjiwvxv2R3IAkkuV2K+ZutuofHTCKs6/Xa1arFUVRYKzB7Tbg2vFS5P9fe+cWa8uWl/XfuNV9Xtda+3L2uXWfWwOixCARAkFUEIwkGi+BoNGQqCRt4oMJT74YH9X4pMHoqzFGAvEBHjC++KBpjERooek+fT19zt5rr8u81b1qjFE+jNm7swn75DShtVczf09VqV2VuWet/6waY/y/70tSLt/7PNun7zNbP0RKwWZzy2q94vb6CqMj0myGp0aKBCEceZGR5zNGC0PXoyaLNjp4LO1u6QeLUgb8gFKC9WpFkyT0fgO0R9UNWDfy6NEr5FnO1dVTbNeTpSl926KV5N5yzmf2B/LRkEUK54NrpPcTdvIwQW8d1lmWWUzTjUgRpHzOeSZnjxlB4FpHnGZoEzGpMFEkJ0eaRExSkGQFX3jvKRbBbncg0YrXXn2FB69+DB3Fwf8qiUOsZ1MRpxN5loQ0hS7kA4HAaInREdZ6rG2wo6UsS+IkQZsURYgTSZIErSP2uy1VVRInKSrO6dvhQ43dTk/aE/zvL3zAqFJMnCKZMCZmMV8w+bBemmY5w2h5cr3jZnsgitPjGqXg+nbDoQma2ygytG0dli0QNHXF6MB7T1PvMErw0v1zztZrtPDgHednF9y//4CmrRiGjjhNkFju37+Hn0CLYNe668IkWRoZ5rHGKEGqNVkckcXxs8QAgFmRc3F+wXq5JMsy3DjS1SVNuaNvDkyTRyoRikRppBDMZzlPbjY8vt1RHiqut1uuNzfYrmGxXJAkaVD8IOh7j4kyqvIQIk28R2tNkqTH1/cQTN00FUkSk6YZ1sN+f8CNHVEUkaY5q9XymEK4x5iI+/ceMM9TVrOEyX6bekTZy6fP7We/9PX9f/L0Z5879u7fMc/tf+4v/sILr/u7f/bfPbf/nf/0Hzzb/vjP/49v+HN+q1NEkjxLeHDxPSRJjDmOsR6//1Vik+CjEak8b772kKbeI7xDqwQ7Cb562/CxByuyvEBJwW57A0LjnEWqsJwhlSBJZ9R1iXOWLEsZxhlddUBrFaR9TctieU5TNzT1jv1hy/nZknfFRG4U9RDaGDOtg32MECEmRCkSpcjjlMqOCOVZzNeczRckEpSJKHcbynLH0HUcygp/u8OOI+f3HpAtVkFnqyRN1XO13aAnh5zAy5jtoWZzc8VE6Ld21rPdl8yLlOVqHRZ6nMd7jzvKAP0EwziGlsnJM5vPghDfBeuarh9JYgnTxHa7CY6MsaJpa7I0C3lESfbC+3Wni/bEHw6pGIjjNWk+Q8uJOJIcyj19b0lTg588Rhq8tyH6wwfh+X57yVsP5qxWc+JIsz/sQpiXlgih8JPHT55Ip0d9qGK0HXbcExmJXqxwdqSqDiRZgXVh2UaqmLxYc7h9ykQYy8ZaMFhPZmBdpGgpEVNISkziGOsnburQXTV5i5scaTKDyXF9exvc/oXA+YGqG9EmIp/NKc7vMdogoTt0FZExnGUFszRn11Zs9tdYBHUT2hajKGIxSyiKjGkK7hmHtiJJIrwPr+lSKIzRyMgQxzF9H/SzUmmUMmw2txT5DDsO2NECEiE1u90e5ybapmbTfJvOHp/4w+H84iFt36PVxGyW0zY15WF3TMVLUUoyuYG6bHF9yTR/gPcNcZKhtMEYiXWW3W6LFBH5LKXrBryw5HnxLPoDJobRk8SGvm0QTAzjSJLkOOe53dziPGRZHqxirGVwlkhJxFFbG2mNVprzIuHi3j3Sey+RLc65fPxVrj/1KRoEVVOzKGbMMoPGo0xCka/CspHvybzD5DlCSFQUs3r0McauZv87n6UfW3a1RccJP/WzP8tyteD+a2+GIlThbS2OY6x1DEPwg/IyRhnDMPSAQGpN3U/kcRhXl2UJSMQUxtir5YrtdhdSGMae8/N7KG2IzEBVVuAHpGteeL9ORXuCOFas1xdM3nH19AlGCWZZgklmmEgHt0JnyGWES3N0FCPlsQ/3KNPbbTc4N+EIDhdSglQKrRRN5zAmwWugsWFtNCuY3AhCBMf+diBJMoah4nA40LYNh9trhmHEAlkU4cXXDM0FblLMP/4J3vie76OYLzG/9b/41K//T7xzKKnYl3seR4bcRCxmaxaLc6Iix00C4yqub55QHbbk9x+CkGTzGT/xl/8Kl+9/hcdf+gJ2GLn/8it84ru+GzuFfmcx+aMGNqLvB5RWbKqePAmi++EomB+tZVnECDy73RZrLVqrIBgwEV0/slgsaBrD5vaGpu2JIwuTw7mBJI5Z3emEge/77mebf/rf/sZHPu3Xf+Z5u463//6nn9v/xL/45LPt3/0b/+pDr/XffuqfPdv+sauff+7YS//8xaHXd4U8TzjsN5SHPfcfvhQKcQp2M5NvcaNHqgilDXGaIoSkHyxZllEUOc5Z6rphsThjt72l61rSLKMfBtqmwk8SHceMw4icRpTKSNOE7e0VflLP1jRvbrdIIbm9uaTc79g++QA7Wjo7IeVEZhSxVqFpwXtwjjzLKfKIR6+/zmI+Z1M2YQkG+O0vf4W377/Mg5ffRuYzTJoT46l3I3K05GezoNyRgte+84+RzOfMZj+KUorqcOD+o5eJ0oxMhzDocRzo+5E4jonjsL48z4IDVdMEV8Wh7zBxRpLEtE1H1/XBu9kJsrxAa4UxjqoK49dxtmS332JtjzQFcaRBKEx0ej0+8SFcX14yWIuJUrIs4+bqKVLFrFYzjBKMXYW3LUIahMmBsFY6jiNCwG67RUpF37eIow3M1dVTzs4usMLhPdRHK1Imy2w2p6q2uEnQlCGgSkvH2XpN37W8/Mrr3Ka3HK6ePkseqIYQBC0zRSwEdhKU2w1xGhNHMfcfvcqb77zD+5dPGcaeIs8wTNDuGW8vUW4kER4tLblypA/vk5w9YJoEaZby8NXXiNIUKVWYGMpnKKVp2xZjLOP4NVuYMKv7tUknoyTOOWazGVpHwEQURc9E7AI4HA4URYEUMCrNzc0WOw4sFxlxYkiHjGFUeA95ljJ0LUKZF9ytU9GeAA5lRTFb8eDBPfq+o+sG0jzhUPXMigxhZmg1IYVnbA94T1geihPGcaRrW5ROuLx6ymq5DuoXEf4Ik2yBlJLUjrgiI0lS/BTGg8ZELM7uo5Riu93i25b1ek1VVYBHRimtdUhg8J7RC5rRIZWniA1KKTY3NyRJQhQlfP+f/3Eev/cV3n/yBINjsV7yO4+fchgHVlnG/YsHzJbnnM806fIMKwRKwitvvYWOkiBK79tjmDZopZimYJQupSSKIpwdsdYiRJAcCiEBQV0PaG2eBWI3TUtd1xijuDg/w0QJQ98wDj1xEiF1mHwah5EsS5gqS93XNI0iiSKa9g6PaV3+9V+cf3z+Wx/5vF/4j9Vz+//yv/74c/tvfdf7H/la79qvt5SdfebFnSp3FX+MYUzSlCcfPCWK06Pbokc1LXIaODz+LOev/wmiZIYWE7Zv6fuGvgm2KwjFerUmz2fsdrecrVfBnQHPoeoxShBHhixPeXr5OIwNjaAfPVIK8jxjtVzRdj1pEvO4H9mVB6puRByjQ3oL0GEk+Cnm5be/k4evvIqJEpRSvPrGm/zNT/5DPvVrv8Lll75AHkfcWxRYoRj6nnGy+H5D+vLHkXGINXn0zid45Y03kXIiL2ZUdYPAMzZleHsYehbLZfBdVophGBgsREajdRRiTNou+BlrSzEr6Puew+GAFBKp9fFHTNA1NTqKyLMsZBTZkSTN2O93pFlG14/c3lyxWq0x0R/BhIETHx0jHJO3NE3J4VAyW5yDt1RNS9MKzldr9PIVBuupd3ukEBhjKPIZ+80VlghtJopiQZrGOL8mjiOaww1SGyIT4+xAXizp2jr07CqBm0RwUwSUCs4XfT9wu7mhrg5cPXlMO1q89yghiI1EThPSW6Sz7G+vkTL8CcdxaKM8O7/g429/B++9+xlc39JsNuyePqY5HEiSlPl6zerRa6xfeolssSYrCtw04RFEccxFljP0HeVBME0TVdUQxRlJHFoLh9GSJBpnB4SIcG5Ca0MURYzjSNu2jEddbJIcTQWAsmqQJsUPDaMNOuPdbksyhiUi5+zRhCC0XpY31y+8X6eiPYE2mslbtrc3aJ2QJAV93zKNHavlBd1gkcVDPC1ZliFFmDia/IBQmjQqcBN0gz1GXYbOIaFTRj/hXEueJSglud7tmKZgCue9J01T4iQOmtRpQmvNwwePeP/LX+WDxx9gXRBvTH5CCIeJNHYS7AZLnM8oipyhDQFWCM2u3JFEmlff/g6WqzVSCA67LV/54rvEUYI0mot7D4iSFESYFe6bGiGCa2LfD8G4TmmmaSJNMwTQdT3OjcH4fJqQOuK2HEmNwMjQEeZ8sIodR4uUCudGlIqDY4ecaOoWOXnSWUxZ7okizQSkWYqzFmsboshwOByom5Oe9sSHcP/hI4au4vZ2A9PE4y9/FiZHlqVIJUkjSabGo761p6pKtFEc9jtCFkBPrD1ZolBKYu1A29QhLV5BpBVpmrLfb0OPbhwdn4xBBzv0bRAgTJ5+6KkOe77wud9+lu+qlXlm7Zpmc2ScIY563b7taKsdkQktlE+uN+zqntX6DGM0u8MWpOSl1z6OznLS2TwUnYCyLLFeMMgZeTELmbZChMb9LCVOEtIkefYK7JxDSo1SmqHr6dua/X6H9xNdUzEMA3VVhnZGrUMcaFlSV83RyFww2hHvLM5anBcgFc4FGzojHWN7QE89afxHMBbk55ZffH7/r/7rP/C1fqN9/dl2/Cv/8w98nW9VkqTAmFuqasNiviJfrPDOMwwdWi0YxxE7jsRxwlFijneOqm5YLM+ZhMTbgb7vkFIds2klfd8fZ2ODWffm9po4ybDWBv/hssLaiUgLhqGjmK8ZveDp5SVf/Py7xxS5cK5WEhNFJFkR1D7aUO73YeInLah210RS8Mp5wauvv4YxmsvLJ3gfGvPvP3iIUgLhHZOUCGWIoxjn4HrXcTabE/J/BCYKwdN13aCkYhwH7t+/4Ob6KkyupQnD0HG2CI6NdmhAGWZ5wW6/oawOZGkGTM++u66tSbM51mrapiWOY0CijaHrapxzdE2Dtz1xNmdp7vI67YlvOhMC6wXz+YIkX9L3LdcffJ5itqJrBxBT6CGWIQ1vuT6jaUoGO7Hd7Y+hXAmREjg30LYVbTcgpSJLU5yzVIcdN7cbZsWMKE5wzuP9RJrECDGhtCFJEhZ5TNtWdG0b1DnakMZJcIcgxHN0fUfXVuyur/DTRF6sGLoGISce3nuA946bmx2270m1J01WjKNnNlswjv1xzBkcMSbXcZGMjF1F5z1xmgf3yLYNgdQ2uP5LKXAuibN0sgAAC25JREFUGJHvthuM0Qgp0VEO0xjEAwhGG2xovHVkeU4cJ+z3O/quRemOvh+xrieNU/xkKcsteZZwfXuLUBplFlgvmMzJjfHEh+KpypKsWFJWJePQka9fJk4SpJSMtse7AaVnTMeZ0+vDlshkKBOWQbwOMZATCqkSsjw59tZ2OO+pa0eehVfQPMuYgDhOYbI0m8eMIqHvh9BYYEzI5UGQ6pAq0A9h1r6aSuq24f5ijvYjk+3QKkOnMXlRkGUpl5dPGYcB7WpUFHyghByYzWfHbqagG3ZuQirP5DuYIqIoZewHZKJwntCiqRQCGMcBPzmUkkSRwUQx42D58uWe1x+u0Dpi6EfStEAISVm3XN1smOcJeTY7itx3oSElXdA2Jd6NdE1F29SYOA9ZP7amOeyQ8t4L79a3fNHGn796tv0zX/qx5479+4/92v/rj/NtyTi0dH1HnE14ESZanm5LLpaQJDFV3SMmi/cht6Zra8qyJk4EfVWzWC5oupF2NCTagQ8WK3EkQSnmiwXbqyck6RJjItw40nYN0mSksWZSMVk6Q+gEPVoePnqFophR1hWRVvhxoB0HumFgFkckRpNEEcuHD5gtV3R9SxKnSK354IMPsNaRJikmSxE6Ik1TyvKAd444iYMCSYQfE+s8Jk7Zlx1pGho51DgeJ8BCi+YEDENYkw2BWYKQyul56Syj3O/I0gSLYkIec28lh+st206xWD8gjmKGaMAYg5wGjPQ8vroJ+UhpSBIcxoHOehoniN2LnVZOE1EnOOx3dN3IMIy0g0OpmHurBVmWMo4ju6rjUNaM40iSxsF5fxKYKDnapySMY4+RlmmyYfkkUmFGFwDP4DxJElNWO3aHA3GSkWcJQiqibMFmu6GrDwgx8Se/9/v4Cz/5k7zx+msMXceyKHDesUhTPnb/Hm8+fMDyfM3L7/xxPIrl4gzvLLfXV5SHA8469mWDiTOss1g7EBlN3TRst1u0ifFTeHpWZRle1YXi8uoq/D8ixWxWYI55QePYB6WOdSFsbBi5vLzk+mZ7bMuUCKXpuo6qrtkfdhwOB3S6oFjeo+saEJ7lcsFkQ6BZ23viZI6McpQ2yKknNhKlIorZGsRpTHviQ+j7jjTLWZ9dAGFSCKFo246by/d49NpbTM4wOYsxhtubkihOiaL4uAQiKMsDDx8UeCTOOowRDP3E+uyMar8JovG6pm1qvHPM5gs4uleMtsc5i3WW9VHf+kM//OcQzvGf3/tF+nFAq9CkcGha3nr7Y/zIX/tbmCShbkaKPCfPc95//32UDn7L02Rxk+R62xCrDWerNVoq6qYliRNmxfyZc2PbNmRpysP7F8zmxXHmt4MpOGsADOOANuY4sRaeguPQcvWlL3D2yjthpni/ZXSwmKfEcUqEI44Mk3d0bcvkLIeqPvpieaJII6xjtJ6mtyxnOYvVmveuas4y9cL7dSraE+x3e7JsSZJEVFVF19TM5ivKvqVrGxSWrrxEzd5gmjxd2yBkipCSpu8YxoFpCp7G1juGvkeKBCU1zjqqqgSZIpCcnd0LzhES9kcFTJpmRMagpCKOIza316Rpyp/6/h/k85/7DKLreOv8O/j0pz/N2SrnB3/kz/Do0SOqqiLRE5FRfPXJU5SJmc+KMCbPi7C8MkmydEacFFhnKYqgW12fnaG1IU1TpJQURQ5C0LYtQgQjOmsdSRKyhZIkxdqR/X6PUprlchm+h/gB/QCOPsR/OE1KwjKLsWNoWMFbuqbhUDWs1mu01rRtj5KKq8sv0XrNpCLU1DNMEc2Y8FDf4Y4o+9WvtxuWPzF77tiP/tDPPbcf/6Mnz7Z/+Z1feu6YES/+5fq9/Ify/nP7v/p3f/jZtuA3P/J17gp12zFfJgx9D5MgSmKkmjg7u+Ds4gKjNUK9jo7S8KrYWYpFHDSzzhMvHpBmLW1bMxHMzuq2Z55HzMlpmxYvLYv5Cikl1nmGwSKkYRxapOxJ4pQoiTFas795irWC9cUFf/vvfZLd5prz+6/y3f/nN3nz46+zXq9DU/9RZXQ47DkcSlbrM7QUdM7SDyOzec5LF7PgWdzVWDvhXUg4GMeRJAlqnf1uT9f1eB+M2aQMJnZ2tGxutxRFhjExQgZxvzHm6LyowJzhR4cWgiyJeL1IWMyzY7DWnv64fiujHG3C20kcG9q243DY03c9Z/fWtF4jjEIMAw9nMvgov4Bv+aI98c2nqlu6YSAaR3oHzgr6zTVCJcTZknHskQjiWNM0Df44nnW2Z7mY0w8tkoEsy2m7njiO0HYkLwq8sxitiNIUrUIaQV4saZoWKQVN19MPI0mSgehpmhovI+bzlCRJmM8KVus15+f3ee211+j6Dte3SKWRCJRW3Nzu0CYmijN2h5Isy6mqDud2qDhlsB7jQqiWmzzDOKJUzjRNYYIJR9O0VHXNcn2PfnChaUQfWyu7nroJs82hAUMxm81pqh1SS6qqprMTq1kCwrPb7ri+foKSYU3XJCFgevL2mEwQlsK2mw3L84c8fPASSkk2tztEYpjlH57+eCraE0QmdCh5PxFrhZeK29KhZXhVjrQgLZYIIWmrEu89dXlAMxJHMb6vmMSEUxLve6IoxWQJWZrQ1sH8LKQLeLyz1G5A6wiTZLz6ystM00TTtthx4PrqKW3bkRcz2m7E2hGjJE25J86XRCaib/aMvSLOsqPf8EgURccOK0kUaYxJqJuSPFqQJzHeW2DCTxOrVWgY2W43FEVBlmUoKegHS1UekDoOYnYHk+/Is5xys6UdHa++dA/vPbebLfP5DDuGPFpjDN5PXN3csNveYMeW9eocbXIEgizLGIeeqq6YKkGaxkgZxsWjE3TjhDYKNcGhHpDT8ML7dZo9PkGaFnRtTVXu6bvuKD3zlIdt6EoSIcHOWkfTNFjv2W03DHbitz77Zdq+R0nJF7/0ZZwPhmV2HBmGgeurSw51hydicJIkXyN0RtuPHPY7dttr2nrH2NXIyTJNHmUi7Gipyi3DaImSDCtitrsdV1dPmeKcKJuhtaYsD9jREccJh7KmrvbHKJGJJMlRUjIMXfgBcIIsn6O1oiz3DP0QXDa0QUeGOI5w1qKlD91XkWQYw3pxliWsZhltU1PXJX4S7KvgG5WmKd7Dfr/j5uYa5yzr9QXL9RlpEoW2zranaQdsVzGJkINkjKFra+zQ0R/7lbt+4PZQU3cvLto79aT15fNN1PGv/p6Wwl/9+uZ3/ZtPPnfoc3/pxe6L7/zi8//247/8/Bem/vtHd8y4i0yTx/Y1WbGgbhrwPUZHFIsVJo6Io4QkTTFaH9P0ElrXs9mXpGnGYj5j6FvOzlZMY8928BSp4SzNsBPkxRw7CW6vbxkHG4zitMZai9GSSRikVmgFfdeEaA8P06SYFbNjby5c3W5ZFilSGsa+YTZbc/V0i3UWk86oBgXCYYeRy6+8y9mDl9FKgZA0/UCGZDbT3Nxc03U9RVGglKbvR5I4Y1ZYkjShLGuGoWccB4o8YfKOwU5HYzjJhCKODE1TMzhHWZbsdhu0kkRaMJ9fUMwK0izDjiGjdxg9aVHgB8Xj6x1xFDGbL7m6vuaDD94nSxOmvKBuGmaROtoM/P7cqaI98c3hp3/mp1+cq/h7eOvtN7+ha7/++qvf8Of5RnjjjTdecOR7X3jOy48efnM+zB+AH/iB7/+Gzzm9Hp84cccQX1so/v34UfnXX3zwxP83/ov/Tx/5yXji24/Tk/bEiTvGqWhPnLhjnIr2xIk7xqloT5y4Y5yK9sSJO8apaE+cuGOcivbEiTvGqWhPnLhjnIr2xIk7xqloT5y4Y5yK9sSJO8apaE+cuGOcivbEiTvGqWhPnLhjfKg078SJE996nJ60J07cMU5Fe+LEHeNUtCdO3DFORXvixB3jVLQnTtwxTkV74sQd4/8CjFX3P+/o5agAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 288x144 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_images((im,im3), titles=('number','puppy'), imsize=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`ArrayImage`, `ArrayImageBW` and `ArrayMask` are subclasses of `ndarray` that know how to show themselves."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayBase(ndarray):\n",
    "    \"An `ndarray` that can modify casting behavior\"\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return x if isinstance(x,ndarray) else array(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBase(ArrayBase):\n",
    "    \"Base class for arrays representing images\"\n",
    "    _show_args = {'cmap':'viridis'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImage(ArrayImageBase):\n",
    "    \"An array representing an image\"\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayImageBW(ArrayImage):\n",
    "    \"An array representing an image\"\n",
    "    _show_args = {'cmap':'Greys'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ArrayMask(ArrayImageBase):\n",
    "    \"An array representing an image mask\"\n",
    "    _show_args = {'alpha':0.5, 'cmap':'tab20', 'interpolation':'nearest'}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_t = cast(im, ArrayImage)\n",
    "test_eq(type(im_t), ArrayImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = im_t.show(figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __array_eq__(self:Tensor,b):\n",
    "    return torch.equal(self,b) if self.dim() else self==b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _array2tensor(x):\n",
    "    if x.dtype==np.uint16: x = x.astype(np.float32)\n",
    "    return torch.from_numpy(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@use_kwargs_dict(dtype=None, device=None, requires_grad=False, pin_memory=False)\n",
    "def tensor(x, *rest, **kwargs):\n",
    "    \"Like `torch.as_tensor`, but handle lists too, and can pass multiple vector elements directly.\"\n",
    "    if len(rest): x = (x,)+rest\n",
    "    # There was a Pytorch bug in dataloader using num_workers>0. Haven't confirmed if fixed\n",
    "    # if isinstance(x, (tuple,list)) and len(x)==0: return tensor(0)\n",
    "    res = (x if isinstance(x, Tensor)\n",
    "           else torch.tensor(x, **kwargs) if isinstance(x, (tuple,list))\n",
    "           else _array2tensor(x) if isinstance(x, ndarray)\n",
    "           else as_tensor(x.values, **kwargs) if isinstance(x, (pd.Series, pd.DataFrame))\n",
    "           else as_tensor(x, **kwargs) if hasattr(x, '__array__') or is_iter(x)\n",
    "           else _array2tensor(array(x), **kwargs))\n",
    "    if res.dtype is torch.float64: return res.float()\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(tensor(torch.tensor([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(array([1,2,3])), torch.tensor([1,2,3]))\n",
    "test_eq(tensor(1,2,3), torch.tensor([1,2,3]))\n",
    "test_eq_type(tensor(1.0), torch.tensor(1.0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def set_seed(s, reproducible=False):\n",
    "    \"Set random seed for `random`, `torch`, and `numpy` (where available)\"\n",
    "    try: torch.manual_seed(s)\n",
    "    except NameError: pass\n",
    "    try: torch.cuda.manual_seed_all(s)\n",
    "    except NameError: pass\n",
    "    try: np.random.seed(s%(2**32-1))\n",
    "    except NameError: pass\n",
    "    random.seed(s)\n",
    "    if reproducible:\n",
    "        torch.backends.cudnn.deterministic = True\n",
    "        torch.backends.cudnn.benchmark = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "set_seed(2*33)\n",
    "a1 = np.random.random()\n",
    "a2 = torch.rand(())\n",
    "a3 = random.random()\n",
    "set_seed(2*33)\n",
    "b1 = np.random.random()\n",
    "b2 = torch.rand(())\n",
    "b3 = random.random()\n",
    "test_eq(a1,b1)\n",
    "test_eq(a2,b2)\n",
    "test_eq(a3,b3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze` but can add `n` dims\"\n",
    "    for _ in range(n): x = x.unsqueeze(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "t2 = unsqueeze(t, n=2)\n",
    "test_eq(t2,t[:,None,None])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def unsqueeze_(x, dim=-1, n=1):\n",
    "    \"Same as `torch.unsqueeze_` but can add `n` dims\"\n",
    "    for _ in range(n): x.unsqueeze_(dim)\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1])\n",
    "unsqueeze_(t, n=2)\n",
    "test_eq(t, tensor([1]).view(1,1,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _fa_rebuild_tensor (cls, *args, **kwargs): return cls(torch._utils._rebuild_tensor_v2(*args, **kwargs))\n",
    "def _fa_rebuild_qtensor(cls, *args, **kwargs): return cls(torch._utils._rebuild_qtensor  (*args, **kwargs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply(func, x, *args, **kwargs):\n",
    "    \"Apply `func` recursively to `x`, passing on args\"\n",
    "    if is_listy(x): return type(x)([apply(func, o, *args, **kwargs) for o in x])\n",
    "    if isinstance(x,dict):  return {k: apply(func, v, *args, **kwargs) for k,v in x.items()}\n",
    "    res = func(x, *args, **kwargs)\n",
    "    return res if x is None else retain_type(res, x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def maybe_gather(x, axis=0):\n",
    "    \"Gather copies of `x` on `axis` (if training is distributed)\"\n",
    "    if num_distrib()<=1: return x\n",
    "    ndim = x.ndim\n",
    "    res = [x.new_zeros(*x.shape if ndim > 0 else (1,)) for _ in range(num_distrib())]\n",
    "    torch.distributed.all_gather(res, x.contiguous() if ndim > 0 else x[None])\n",
    "    return torch.cat(res, dim=axis) if ndim > 0 else torch.cat(res, dim=axis).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_detach(b, cpu=True, gather=True):\n",
    "    \"Recursively detach lists of tensors in `b `; put them on the CPU if `cpu=True`.\"\n",
    "    def _inner(x, cpu=True, gather=True):\n",
    "        if not isinstance(x,Tensor): return x\n",
    "        x = x.detach()\n",
    "        if gather: x = maybe_gather(x)\n",
    "        return x.cpu() if cpu else x\n",
    "    return apply(_inner, b, cpu=cpu, gather=gather)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`gather` only applies during distributed training and the result tensor will be the one gathered across processes if `gather=True` (as a result, the batch size will be multiplied by the number of processes)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_half(b):\n",
    "    \"Recursively map lists of tensors in `b ` to FP16.\"\n",
    "    return apply(lambda x: x.half() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_float(b):\n",
    "    \"Recursively map lists of int tensors in `b ` to float.\"\n",
    "    return apply(lambda x: x.float() if torch.is_floating_point(x) else x, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# None: True if available; True: error if not available; False: use CPU\n",
    "defaults.use_cuda = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def default_device(use_cuda=-1):\n",
    "    \"Return or set default device; `use_cuda`: None - CUDA if available; True - error if not available; False - CPU\"\n",
    "    if use_cuda != -1: defaults.use_cuda=use_cuda\n",
    "    use = defaults.use_cuda or (torch.cuda.is_available() and defaults.use_cuda is None)\n",
    "    assert torch.cuda.is_available() or not use\n",
    "    return torch.device(torch.cuda.current_device()) if use else torch.device('cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "_td = torch.device(torch.cuda.current_device())\n",
    "test_eq(default_device(None), _td)\n",
    "test_eq(default_device(True), _td)\n",
    "test_eq(default_device(False), torch.device('cpu'))\n",
    "default_device(None);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_device(b, device=None):\n",
    "    \"Recursively put `b` on `device`.\"\n",
    "    if defaults.use_cuda==False: device='cpu'\n",
    "    elif device is None: device=default_device()\n",
    "    def _inner(o): return o.to(device, non_blocking=True) if isinstance(o,Tensor) else o.to_device(device) if hasattr(o, \"to_device\") else o\n",
    "    return apply(_inner, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = to_device((3,(tensor(3),tensor(2))))\n",
    "t1,(t2,t3) = t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cuda\n",
    "test_eq_type(t,(3,(tensor(3).cuda(),tensor(2).cuda())))\n",
    "test_eq(t2.type(), \"torch.cuda.LongTensor\")\n",
    "test_eq(t3.type(), \"torch.cuda.LongTensor\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_cpu(b):\n",
    "    \"Recursively map lists of tensors in `b ` to the cpu.\"\n",
    "    return to_device(b,'cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_cpu(t3)\n",
    "test_eq(t3.type(), \"torch.LongTensor\")\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_np(x):\n",
    "    \"Convert a tensor to a numpy array.\"\n",
    "    return apply(lambda o: o.data.cpu().numpy(), x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t3 = to_np(t3)\n",
    "test_eq(type(t3), np.ndarray)\n",
    "test_eq(t3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def to_concat(xs, dim=0):\n",
    "    \"Concat the element in `xs` (recursively if they are tuples/lists of tensors)\"\n",
    "    if not xs: return xs\n",
    "    if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])\n",
    "    if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs[0].keys()}\n",
    "    #We may receive xs that are not concatenable (inputs of a text classifier for instance),\n",
    "    #   in this case we return a big list\n",
    "    try:    return retain_type(torch.cat(xs, dim=dim), xs[0])\n",
    "    except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])\n",
    "                          for i in range_of(o_)) for o_ in xs], L())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(to_concat([tensor([1,2]), tensor([3,4])]), tensor([1,2,3,4]))\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4]])], dim=1), tensor([[1,2,3,4]]))\n",
    "test_eq_type(to_concat([(tensor([1,2]), tensor([3,4])), (tensor([3,4]), tensor([5,6]))]), (tensor([1,2,3,4]), tensor([3,4,5,6])))\n",
    "test_eq_type(to_concat([[tensor([1,2]), tensor([3,4])], [tensor([3,4]), tensor([5,6])]]), [tensor([1,2,3,4]), tensor([3,4,5,6])])\n",
    "test_eq_type(to_concat([(tensor([1,2]),), (tensor([3,4]),)]), (tensor([1,2,3,4]),))\n",
    "\n",
    "test_eq(to_concat([tensor([[1,2]]), tensor([[3,4], [5,6]])], dim=1), [tensor([1]),tensor([3, 5]),tensor([4, 6])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(type(to_concat([dict(foo=tensor([1,2]), bar=tensor(3,4))])), dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tensor subtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def set_meta(self:Tensor, x, copy_meta=False):\n",
    "    \"Set all metadata in `__dict__`\"\n",
    "    if not hasattr(x,'__dict__'): return\n",
    "    d = x.__dict__\n",
    "    if copy_meta:\n",
    "        d = copy(d)\n",
    "        if '_meta' in d: d['_meta'] = copy(d['_meta'])\n",
    "    self.__dict__ = d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def get_meta(self:Tensor, n, d=None):\n",
    "    \"Set `n` from `self._meta` if it exists and returns default `d` otherwise\"\n",
    "    return getattr(self, '_meta', {}).get(n, d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(torch,'as_subclass'):\n",
    "    setattr(torch, 'as_subclass', torch.Tensor.as_subclass)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def as_subclass(self:Tensor, typ):\n",
    "    \"Cast to `typ` and include `__dict__` and meta\"\n",
    "    return retain_meta(self, torch.as_subclass(self, typ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Tensor.set_meta` and `Tensor.as_subclass` work together to maintain `_meta` after casting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(Tensor): pass\n",
    "t = tensor(1.).requires_grad_()\n",
    "t._meta = {'img_size': 1}\n",
    "t2 = t.as_subclass(_T)\n",
    "test_eq(t._meta, t2._meta)\n",
    "test_eq(t2.get_meta('img_size'), 1)\n",
    "assert(t2.requires_grad_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorBase(Tensor):\n",
    "    def __new__(cls, x, **kwargs):\n",
    "        res = cast(tensor(x), cls)\n",
    "        if kwargs: res._meta = kwargs\n",
    "        return res\n",
    "\n",
    "    @classmethod\n",
    "    def _before_cast(cls, x): return tensor(x)\n",
    "\n",
    "    def __reduce_ex__(self,proto):\n",
    "        torch.utils.hooks.warn_if_has_hooks(self)\n",
    "        args = (type(self), self.storage(), self.storage_offset(), tuple(self.size()), self.stride())\n",
    "        if self.is_quantized: args = args + (self.q_scale(), self.q_zero_point())\n",
    "        f = _fa_rebuild_qtensor if self.is_quantized else  _fa_rebuild_tensor\n",
    "        return (f, args + (self.requires_grad, OrderedDict()))\n",
    "\n",
    "    def gi(self, i):\n",
    "        res = self[i]\n",
    "        return res.as_subclass(type(self)) if isinstance(res,Tensor) else res\n",
    "\n",
    "    def __repr__(self):\n",
    "        return re.sub('tensor', self.__class__.__name__, super().__repr__())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _patch_tb():\n",
    "    if getattr(TensorBase,'_patched',False): return\n",
    "    TensorBase._patched = True\n",
    "\n",
    "    def get_f(fn):\n",
    "        def _f(self, *args, **kwargs):\n",
    "            cls = self.__class__\n",
    "            res = getattr(super(TensorBase, self), fn)(*args, **kwargs)\n",
    "            return retain_type(res, self, copy_meta=True)\n",
    "        return _f\n",
    "\n",
    "    t = tensor([1])\n",
    "    skips = 'as_subclass imag real __getitem__ __class__ __deepcopy__ __delattr__ __dir__ __doc__ __getattribute__ __hash__ __init__ \\\n",
    "        __init_subclass__ __new__ __reduce__ __reduce_ex__ __repr__ __module__ __setstate__'.split()\n",
    "\n",
    "    for fn in dir(t):\n",
    "        if fn in skips: continue\n",
    "        f = getattr(t, fn)\n",
    "        if isinstance(f, (MethodWrapperType, BuiltinFunctionType, BuiltinMethodType, MethodType, FunctionType)):\n",
    "            setattr(TensorBase, fn, get_f(fn))\n",
    "\n",
    "_patch_tb()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorCategory(TensorBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export \n",
    "class TensorMultiCategory(TensorCategory): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class _T(TensorBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = _T(range(5))\n",
    "test_eq(t[0], 0)\n",
    "test_eq_type(t.gi(0), _T(0))\n",
    "test_eq_type(t.gi(slice(2)), _T([0,1]))\n",
    "test_eq_type(t+1, _T(range(1,6)))\n",
    "test_eq(repr(t), '_T([0, 1, 2, 3, 4])')\n",
    "\n",
    "test_eq(type(pickle.loads(pickle.dumps(t))), _T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "m = TensorBase([False,True,True])\n",
    "test_eq(t[m], tensor([2,3]))\n",
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "m = cast(tensor([[False,True,True],\n",
    "                 [False,True,True]]), TensorBase)\n",
    "test_eq(t[m], tensor([2,3,2,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([[1,2,3],[1,2,3]])\n",
    "t._meta = {'img_size': 1}\n",
    "t2 = cast(t, TensorBase)\n",
    "test_eq(t2._meta, t._meta)\n",
    "x = retain_type(tensor([4,5,6]), t2)\n",
    "test_eq(x._meta, t._meta)\n",
    "t3 = TensorBase([[1,2,3],[1,2,3]], img_size=1)\n",
    "test_eq(t3._meta, t._meta)\n",
    "t4 = t2+1\n",
    "t4._meta['img_size'] = 2\n",
    "test_eq(t2._meta, {'img_size': 1})\n",
    "test_eq(t4._meta, {'img_size': 2})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBase(TensorBase):\n",
    "    _show_args = ArrayImageBase._show_args\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImage(TensorImageBase): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorImageBW(TensorImage): _show_args = ArrayImageBW._show_args"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TensorMask(TensorImageBase):\n",
    "    _show_args = ArrayMask._show_args\n",
    "\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        codes = self.get_meta('codes')\n",
    "        if codes is not None: kwargs = merge({'vmin': 1, 'vmax': len(codes)}, kwargs)\n",
    "        return super().show(ctx=ctx, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = Image.open(TEST_IMAGE)\n",
    "im_t = cast(array(im), TensorImage)\n",
    "test_eq(type(im_t), TensorImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im_t2 = cast(tensor(1), TensorMask)\n",
    "test_eq(type(im_t2), TensorMask)\n",
    "test_eq(im_t2, tensor(1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 144x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax = im_t.show(figsize=(2,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_fig_exists(ax)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide (last test of to_concat)\n",
    "test_eq_type(to_concat([TensorImage([1,2]), TensorImage([3,4])]), TensorImage([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class TitledTensorScalar(TensorBase):\n",
    "    \"A tensor containing a scalar that has a `show` method\"\n",
    "    def show(self, **kwargs): show_title(self.item(), **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## L -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def tensored(self:L):\n",
    "    \"`mapped(tensor)`\"\n",
    "    return self.map(tensor)\n",
    "@patch\n",
    "def stack(self:L, dim=0):\n",
    "    \"Same as `torch.stack`\"\n",
    "    return torch.stack(list(self.tensored()), dim=dim)\n",
    "@patch\n",
    "def cat  (self:L, dim=0):\n",
    "    \"Same as `torch.cat`\"\n",
    "    return torch.cat  (list(self.tensored()), dim=dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.tensored\" class=\"doc_header\"><code>L.tensored</code><a href=\"__main__.py#L2\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.tensored</code>()\n",
       "\n",
       "`mapped(tensor)`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.tensored)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are shortcuts for `torch.stack` and `torch.cat` if your `L` contains tensors or something convertible. You can manually convert with `tensored`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = L(([1,2],[3,4]))\n",
    "test_eq(t.tensored(), [tensor(1,2),tensor(3,4)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.stack\" class=\"doc_header\"><code>L.stack</code><a href=\"__main__.py#L6\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.stack</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.stack`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.stack(), tensor([[1,2],[3,4]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h4 id=\"L.cat\" class=\"doc_header\"><code>L.cat</code><a href=\"__main__.py#L10\" class=\"source_link\" style=\"float:right\">[source]</a></h4>\n",
       "\n",
       "> <code>L.cat</code>(**`dim`**=*`0`*)\n",
       "\n",
       "Same as `torch.cat`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(L.cat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(t.cat(), tensor([1,2,3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chunks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def concat(*ls):\n",
    "    \"Concatenate tensors, arrays, lists, or tuples\"\n",
    "    if not len(ls): return []\n",
    "    it = ls[0]\n",
    "    if isinstance(it,torch.Tensor): res = torch.cat(ls)\n",
    "    elif isinstance(it,ndarray): res = np.concatenate(ls)\n",
    "    else:\n",
    "        res = itertools.chain.from_iterable(map(L,ls))\n",
    "        if isinstance(it,(tuple,list)): res = type(it)(res)\n",
    "        else: res = L(res)\n",
    "    return retain_type(res, it)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b,c = [1],[1,2],[1,1,2]\n",
    "test_eq(concat(a,b), c)\n",
    "test_eq_type(concat(tuple (a),tuple (b)), tuple (c))\n",
    "test_eq_type(concat(array (a),array (b)), array (c))\n",
    "test_eq_type(concat(tensor(a),tensor(b)), tensor(c))\n",
    "test_eq_type(concat(TensorBase(a),TensorBase(b)), TensorBase(c))\n",
    "test_eq_type(concat([1,1],1), [1,1,1])\n",
    "test_eq_type(concat(1,1,1), L(1,1,1))\n",
    "test_eq_type(concat(L(1,2),1), L(1,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Chunks:\n",
    "    \"Slice and int indexing into a list of lists\"\n",
    "    def __init__(self, chunks, lens=None):\n",
    "        self.chunks = chunks\n",
    "        self.lens = L(map(len,self.chunks) if lens is None else lens)\n",
    "        self.cumlens = np.cumsum(0+self.lens)\n",
    "        self.totlen = self.cumlens[-1]\n",
    "\n",
    "    def __getitem__(self,i):\n",
    "        if isinstance(i,slice): return retain_type(self.getslice(i), old=self.chunks[0])\n",
    "        di,idx = self.doc_idx(i)\n",
    "        return retain_type(self.chunks[di][idx], old=self.chunks[0])\n",
    "\n",
    "    def getslice(self, i):\n",
    "        st_d,st_i = self.doc_idx(ifnone(i.start,0))\n",
    "        en_d,en_i = self.doc_idx(ifnone(i.stop,self.totlen+1))\n",
    "        res = [self.chunks[st_d][st_i:(en_i if st_d==en_d else sys.maxsize)]]\n",
    "        for b in range(st_d+1,en_d): res.append(self.chunks[b])\n",
    "        if st_d!=en_d and en_d<len(self.chunks): res.append(self.chunks[en_d][:en_i])\n",
    "        return concat(*res)\n",
    "\n",
    "    def doc_idx(self, i):\n",
    "        if i<0: i=self.totlen+i # count from end\n",
    "        docidx = np.searchsorted(self.cumlens, i+1)-1\n",
    "        cl = self.cumlens[docidx]\n",
    "        return docidx,i-cl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(list(string.ascii_lowercase[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], ['a','b','c','d','e'])\n",
    "test_eq([b[-o] for o in range(1,6)], ['z','y','x','w','v'])\n",
    "test_eq(b[6:13], 'g,h,i,j,k,l,m'.split(','))\n",
    "test_eq(b[20:77], 'u,v,w,x,y,z'.split(','))\n",
    "test_eq(b[:5], 'a,b,c,d,e'.split(','))\n",
    "test_eq(b[:2], 'a,b'.split(','))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = torch.arange(26)\n",
    "docs = L(t[a:b] for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq([b[ o] for o in range(0,5)], range(0,5))\n",
    "test_eq([b[-o] for o in range(1,6)], [25,24,23,22,21])\n",
    "test_eq(b[6:13], torch.arange(6,13))\n",
    "test_eq(b[20:77], torch.arange(20,26))\n",
    "test_eq(b[:5], torch.arange(5))\n",
    "test_eq(b[:2], torch.arange(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = L(TensorBase(t[a:b]) for a,b in ((0,3),(3,7),(7,8),(8,16),(16,24),(24,26)))\n",
    "b = Chunks(docs)\n",
    "test_eq_type(b[:2], TensorBase(range(2)))\n",
    "test_eq_type(b[:5], TensorBase(range(5)))\n",
    "test_eq_type(b[9:13], TensorBase(range(9,13)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simple types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_title(o, ax=None, ctx=None, label=None, color='black', **kwargs):\n",
    "    \"Set title of `ax` to `o`, or print `o` if `ax` is `None`\"\n",
    "    ax = ifnone(ax,ctx)\n",
    "    if ax is None: print(o)\n",
    "    elif hasattr(ax, 'set_title'):\n",
    "        t = ax.title.get_text()\n",
    "        if len(t) > 0: o = t+'\\n'+str(o)\n",
    "        ax.set_title(o, color=color)\n",
    "    elif isinstance(ax, pd.Series):\n",
    "        while label in ax: label += '_'\n",
    "        ax = ax.append(pd.Series({label: o}))\n",
    "    return ax"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: show_title(\"title\"), \"title\")\n",
    "# ensure that col names are unique when showing to a pandas series\n",
    "assert show_title(\"title\", ctx=pd.Series(dict(a=1)), label='a').equals(pd.Series(dict(a=1,a_='title')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class ShowTitle:\n",
    "    \"Base class that adds a simple `show`\"\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledInt(Int, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledFloat(Float, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledStr(Str, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "class TitledTuple(fastuple, ShowTitle):\n",
    "    _show_args = {'label': 'text'}\n",
    "    def show(self, ctx=None, **kwargs):\n",
    "        \"Show self\"\n",
    "        return show_title(str(self), ctx=ctx, **merge(self._show_args, kwargs))\n",
    "\n",
    "add_docs(TitledInt, \"An `int` with `show`\"); add_docs(TitledStr, \"An `str` with `show`\");\n",
    "add_docs(TitledFloat, \"A `float` with `show`\"); add_docs(TitledTuple, \"A `fastuple` with `show`\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledInt\" class=\"doc_header\"><code>class</code> <code>TitledInt</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledInt</code>() :: `Int`\n",
       "\n",
       "An `int` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledInt, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledStr\" class=\"doc_header\"><code>class</code> <code>TitledStr</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledStr</code>() :: `Str`\n",
       "\n",
       "An `str` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledStr, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledFloat\" class=\"doc_header\"><code>class</code> <code>TitledFloat</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledFloat</code>(**`x`**=*`0`*) :: `Float`\n",
       "\n",
       "A `float` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledFloat, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_stdout(lambda: TitledStr('s').show(), 's')\n",
    "test_stdout(lambda: TitledInt(1).show(), '1')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"TitledTuple\" class=\"doc_header\"><code>class</code> <code>TitledTuple</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>TitledTuple</code>(**`x`**=*`None`*, **\\*`rest`**) :: `fastuple`\n",
       "\n",
       "A `fastuple` with `show`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(TitledTuple, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "df = pd.DataFrame(index = range(1))\n",
    "row = df.iloc[0]\n",
    "x = TitledFloat(2.56)\n",
    "row = x.show(ctx=row, label='lbl')\n",
    "test_eq(float(row.lbl), 2.56)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def truncate(self:TitledStr, n):\n",
    "    \"Truncate self to `n`\"\n",
    "    words = self.split(' ')[:n]\n",
    "    return TitledStr(' '.join(words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "if not hasattr(pd.DataFrame,'_old_init'): pd.DataFrame._old_init = pd.DataFrame.__init__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def __init__(self:pd.DataFrame, data=None, index=None, columns=None, dtype=None, copy=False):\n",
    "    if data is not None and isinstance(data, Tensor): data = to_np(data)\n",
    "    self._old_init(data, index=index, columns=columns, dtype=dtype, copy=copy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_empty_df(n):\n",
    "    \"Return `n` empty rows of a dataframe\"\n",
    "    df = pd.DataFrame(index = range(n))\n",
    "    return [df.iloc[i] for i in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def display_df(df):\n",
    "    \"Display `df` in a notebook or defaults to print\"\n",
    "    try: from IPython.display import display, HTML\n",
    "    except: return print(df)\n",
    "    display(HTML(df.to_html()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def get_first(c):\n",
    "    \"Get the first element of c, even if c is a dataframe\"\n",
    "    return getattr(c, 'iloc', c)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_param(m):\n",
    "    \"First parameter in `m`\"\n",
    "    return first(m.parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def item_find(x, idx=0):\n",
    "    \"Recursively takes the `idx`-th element of `x`\"\n",
    "    if is_listy(x): return item_find(x[idx])\n",
    "    if isinstance(x,dict):\n",
    "        key = list(x.keys())[idx] if isinstance(idx, int) else idx\n",
    "        return item_find(x[key])\n",
    "    return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_device(b):\n",
    "    \"Recursively search the device of `b`.\"\n",
    "    return item_find(b).device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t2 = to_device(tensor(0))\n",
    "dev = default_device()\n",
    "test_eq(find_device(t2), dev)\n",
    "test_eq(find_device([t2,t2]), dev)\n",
    "test_eq(find_device({'a':t2,'b':t2}), dev)\n",
    "test_eq(find_device({'a':[[t2],[t2]],'b':t2}), dev)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def find_bs(b):\n",
    "    \"Recursively search the batch size of `b`.\"\n",
    "    return item_find(b).shape[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = torch.randn(4,5)\n",
    "test_eq(find_bs(x), 4)\n",
    "test_eq(find_bs([x, x]), 4)\n",
    "test_eq(find_bs({'a':x,'b':x}), 4)\n",
    "test_eq(find_bs({'a':[[x],[x]],'b':x}), 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def np_func(f):\n",
    "    \"Convert a function taking and returning numpy arrays to one taking and returning tensors\"\n",
    "    def _inner(*args, **kwargs):\n",
    "        nargs = [to_np(arg) if isinstance(arg,Tensor) else arg for arg in args]\n",
    "        return tensor(f(*nargs, **kwargs))\n",
    "    functools.update_wrapper(_inner, f)\n",
    "    return _inner"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This decorator is particularly useful for using numpy functions as fastai metrics, for instance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import f1_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@np_func\n",
    "def f1(inp,targ): return f1_score(targ, inp)\n",
    "\n",
    "a1,a2 = array([0,1,1]),array([1,0,1])\n",
    "t = f1(tensor(a1),tensor(a2))\n",
    "test_eq(f1_score(a1,a2), t)\n",
    "assert isinstance(t,Tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class Module(nn.Module, metaclass=PrePostInitMeta):\n",
    "    \"Same as `nn.Module`, but no need for subclasses to call `super().__init__`\"\n",
    "    def __pre_init__(self, *args, **kwargs): super().__init__()\n",
    "    def __init__(self): pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "<h3 id=\"Module\" class=\"doc_header\"><code>class</code> <code>Module</code><a href=\"\" class=\"source_link\" style=\"float:right\">[source]</a></h3>\n",
       "\n",
       "> <code>Module</code>() :: [`Module`](/torch_core#Module)\n",
       "\n",
       "Same as `nn.Module`, but no need for subclasses to call `super().__init__`"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_doc(Module, title_level=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-1.0893], grad_fn=<AddBackward0>)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class _T(Module):\n",
    "    def __init__(self): self.f = nn.Linear(1,1)\n",
    "    def forward(self,x): return self.f(x)\n",
    "\n",
    "t = _T()\n",
    "t(tensor([1.]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "from torch.nn.parallel import DistributedDataParallel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def get_model(model):\n",
    "    \"Return the model maybe wrapped inside `model`.\"\n",
    "    return model.module if isinstance(model, (DistributedDataParallel, nn.DataParallel)) else model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def one_hot(x, c):\n",
    "    \"One-hot encode `x` with `c` classes.\"\n",
    "    res = torch.zeros(c, dtype=torch.uint8)\n",
    "    if isinstance(x, Tensor) and x.numel()>0: res[x] = 1.\n",
    "    else: res[list(L(x, use_list=None))] = 1.\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot([1,4], 5), tensor(0,1,0,0,1).byte())\n",
    "test_eq(one_hot(torch.tensor([]), 5), tensor(0,0,0,0,0).byte())\n",
    "test_eq(one_hot(2, 5), tensor(0,0,1,0,0).byte())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def one_hot_decode(x, vocab=None):\n",
    "    return L(vocab[i] if vocab else i for i,x_ in enumerate(x) if x_==1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_eq(one_hot_decode(tensor(0,1,0,0,1)), [1,4])\n",
    "test_eq(one_hot_decode(tensor(0,0,0,0,0)), [   ])\n",
    "test_eq(one_hot_decode(tensor(0,0,1,0,0)), [2  ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def params(m):\n",
    "    \"Return all parameters of `m`\"\n",
    "    return [p for p in m.parameters()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def trainable_params(m):\n",
    "    \"Return all trainable parameters of `m`\"\n",
    "    return [p for p in m.parameters() if p.requires_grad]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = nn.Linear(4,5)\n",
    "test_eq(trainable_params(m), [m.weight, m.bias])\n",
    "m.weight.requires_grad_(False)\n",
    "test_eq(trainable_params(m), [m.bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "norm_types = (nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d, nn.InstanceNorm1d, nn.InstanceNorm2d, nn.InstanceNorm3d, nn.LayerNorm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def norm_bias_params(m, with_bias=True):\n",
    "    \"Return all bias and BatchNorm parameters\"\n",
    "    if isinstance(m, norm_types): return L(m.parameters())\n",
    "    res = L(m.children()).map(norm_bias_params, with_bias=with_bias).concat()\n",
    "    if with_bias and getattr(m, 'bias', None) is not None: res.append(m.bias)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for norm_func in [nn.BatchNorm1d, partial(nn.InstanceNorm1d, affine=True)]:\n",
    "    model = nn.Sequential(nn.Linear(10,20), norm_func(20), nn.Conv1d(3,4, 3))\n",
    "    test_eq(norm_bias_params(model), [model[0].bias, model[1].weight, model[1].bias, model[2].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20, bias=False), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model), [model[1][0].weight, model[1][0].bias, model[1][1].bias])\n",
    "    model = nn.ModuleList([nn.Linear(10,20), nn.Sequential(norm_func(20), nn.Conv1d(3,4,3))])\n",
    "    test_eq(norm_bias_params(model, with_bias=False), [model[1][0].weight, model[1][0].bias])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def batch_to_samples(b, max_n=10):\n",
    "    \"'Transposes' a batch to (at most `max_n`) samples\"\n",
    "    if isinstance(b, Tensor): return retain_types(list(b[:max_n]), [b])\n",
    "    else:\n",
    "        res = L(b).map(partial(batch_to_samples,max_n=max_n))\n",
    "        return retain_types(res.zip(), [b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = tensor([1,2,3])\n",
    "test_eq(batch_to_samples([t,t+1], max_n=2), ([1,2],[2,3]))\n",
    "test_eq(batch_to_samples(tensor([1,2,3]), 10), [1, 2, 3])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 10), [(1, 4), (2, 5), (3, 6)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), tensor([4,5,6])], 2), [(1, 4), (2, 5)])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 10), \n",
    "        [(1, (4, 7)), (2, (5, 8)), (3, (6, 9))])\n",
    "test_eq(batch_to_samples([tensor([1,2,3]), [tensor([4,5,6]),tensor([7,8,9])]], 2), [(1, (4, 7)), (2, (5, 8))])\n",
    "\n",
    "t = fastuple(tensor([1,2,3]),TensorBase([2,3,4]))\n",
    "test_eq_type(batch_to_samples(t)[0][1], TensorBase(2))\n",
    "test_eq(batch_to_samples(t).map(type), [fastuple]*3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def interp_1d(x:Tensor, xp, fp):\n",
    "    \"Same as `np.interp`\"\n",
    "    slopes = (fp[1:]-fp[:-1])/(xp[1:]-xp[:-1])\n",
    "    incx = fp[:-1] - (slopes*xp[:-1])\n",
    "    locs = (x[:,None]>=xp[None,:]).long().sum(1)-1\n",
    "    locs = locs.clamp(0,len(slopes)-1)\n",
    "    return slopes[locs]*x + incx[locs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAYB0lEQVR4nO3df3Ac9Z3m8ffnZKU0y4LF2totLPmQcmVkNrKQvAJM5LvzxjHilxctAQcSEqAoHBJ+5IqUg13J+jiHKnvjVOBcMaFcxAep24JSWK3WBg5lYwML2XBnGRnJNogVxuAZJYcwK19YjxdJ/twfMxIjaYRG0sgz3XpeVapRf7s1/SDMQ7u759vm7oiISPD9u1wHEBGR7FChi4iEhApdRCQkVOgiIiGhQhcRCYk5udrx/Pnzvby8PFe7FxEJpP3793/g7iXp1uWs0MvLy2lra8vV7kVEAsnM3h1vnU65iIiEhApdRCQkVOgiIiGRs3Po6fT39xONRjl16lSuo+SNoqIiysrKKCwszHUUEclzeVXo0WiUs88+m/Lycsws13Fyzt05fvw40WiUioqKXMcRkTw34SkXM9tpZu+b2cFx1puZbTOzbjPrMLOlUw1z6tQp5s2bpzJPMjPmzZunv7GIhERLe4z6LXupWP8s9Vv20tIey+r7Z3KE/jjwE+Dn46y/EliU/LoU+GnydUpU5iPp9yESUB1NsGcTnIjC3DL2/Yd72LDvfOL9gwDE+uJsaO4EoLG2NCu7nPAI3d3/EfjwUza5Fvi5J7wKFJvZeVlJJyISRB1NsPteOHEMcDhxjKrX/opVgy+N2CzeP8jW1q6s7TYbd7mUAsdSlqPJsTHMbK2ZtZlZW29vbxZ2nX1Hjx6lqqoq6++7YsUKfZBKZLbYswn64yOGIvwb353TNGbTnr74mLGpykahpzsnkPapGe6+w93r3L2upCTtJ1cDYXBwMNcRRCSfnYimHV5gx8eOFUeytttsFHoUWJiyXAb0ZOF9JzRTFxgGBga45ZZbqK6u5vrrr+fkyZOUl5ezadMmli9fzi9+8Qt++ctfctlll7F06VJuuOEGPvroIwA2bdrExRdfTFVVFWvXrmX0E6FOnz7NLbfcwve//30GBwe59dZbqaqqYsmSJTz00ENZyS8iOTa3LO3wb5k3YjlSWMC6hsqs7TYbhb4L+HrybpdlwAl3/20W3vdTtbTH2NDcSawvjvPJBYZslHpXVxdr166lo6ODc845h0ceeQRI3BP+yiuv8MUvfpEHH3yQX/3qV7z22mvU1dXx4x//GIC7776bffv2cfDgQeLxOM8888zw+w4MDPDVr36VCy64gAcffJADBw4Qi8U4ePAgnZ2d3HbbbdPOLiJ5YOVGKBx15F0YoefPvktpcQQDSosjbL5uSdYuiEIGd7mY2ZPACmC+mUWB/woUArj7o8BzwFVAN3ASOCOttLW1a/hq8ZChCwzT/QUtXLiQ+vp6AG6++Wa2bdsGwJe//GUAXn31VQ4fPjy8zccff8xll10GwAsvvMAPf/hDTp48yYcffsjnPvc5Vq9eDcA3vvEN1qxZw/e+9z0APvvZz3LkyBHuuecerr76ai6//PJp5RaRPFG9JvGacpcLKzdycfUafv0XM7fbCQvd3W+aYL0Dd2UtUYbGu5CQjQsMo28VHFo+66yzgMQHflatWsWTTz45YrtTp07xrW99i7a2NhYuXMgDDzww4h7yz3/+87zwwgt85zvfoaioiHPPPZfXX3+d1tZWtm/fTlNTEzt37px2fhHJA9VrPin2MySwc7mMdyEhGxcY3nvvPX7zm98A8OSTT7J8+fIR65ctW8avf/1ruru7ATh58iRvvfXWcHnPnz+fjz76iKeffnrEz91+++1cddVV3HDDDQwMDPDBBx9w+vRpvvSlL/GDH/yA1157bdrZRWT2Cmyhr2uoJFJYMGIsWxcYLrzwQp544gmqq6v58MMP+eY3vzlifUlJCY8//jg33XQT1dXVLFu2jDfffJPi4mLuuOMOlixZQmNjIxdffPGY977vvvtYunQpX/va14jFYqxYsYKamhpuvfVWNm/ePO3sIjJ72ei7MM6Uuro6H31f9htvvMGFF16Y8Xu0tMfY2tpFT1+cBcUR1jVUZvUCQ76Y7O9FRMLLzPa7e126dXk1OddkNdaWhrLARUSmIrCnXEREZCQVuohISKjQRURCQoUuIhISKnQRkZBQoc+gF198kWuuuSbXMURkllChT4GmzxWRfBTsQu9ogoeq4IHixGvH2MnjJ+vo0aMsXrx4ytPnPv/88yxevJjly5fT3Nw8/L4vvfQSNTU11NTUUFtby+9///tpZxURSRXcQk/ziCd235uVUp/q9LmnTp3ijjvuYPfu3bz88sv87ne/G37PH/3oR2zfvp0DBw7w8ssvE4lkb1J7EREIcqGnecQT/fHE+DSNnj73lVdeAdJPn1tTU8MTTzzBu+++y5tvvklFRQWLFi3CzLj55puH37O+vp777ruPbdu20dfXx5w5gf6QrojkoeAW+jiPeBp3fBIynT73wIEDHDhwgMOHD/Ozn/0s7c8OWb9+PY899hjxeHx4Mi8RkWwKbqGP84incccnYarT5y5evJh33nmHt99+e/hnh7z99tssWbKE+++/n7q6OhW6iGRdcAt9nEc8sXLjtN96qtPnFhUVsWPHDq6++mqWL1/O+eefP/wzDz/8MFVVVVx00UVEIhGuvPLKaecUEUkV6Olz6Wga84in6T4h5OjRo1xzzTUcPHhwWu+TTZo+V0SGhHb63Fw84klEJF8F95TLDCkvL8+ro3MRkUzlXaHn6hRQvtLvQ0QylVeFXlRUxPHjx1ViSe7O8ePHKSoqynUUEQmAvDqHXlZWRjQapbe3N9dR8kZRURFlZdO/FVNEwi+vCr2wsJCKiopcxxARCaS8OuUiIiJTp0IXEQkJFbqISEio0EVEQkKFLiISEip0EZGQUKGLiIRERoVuZleYWZeZdZvZ+jTr55rZbjN73cwOmdlt2Y+av1raY9Rv2UvF+mep37KXlvZYriOJyCw04QeLzKwA2A6sAqLAPjPb5e6HUza7Czjs7qvNrAToMrO/cfePZyR1Hmlpj7GhuZN4/yAAsb44G5o7AWisLc1lNBGZZTI5Qr8E6Hb3I8mCfgq4dtQ2Dpxtieev/SHwITCQ1aR5amtr13CZD4n3D7K1tStHiURktsqk0EuBYynL0eRYqp8AFwI9QCfwbXc/PfqNzGytmbWZWVtY5mvp6YtPalxEZKZkUujpnno8ejrEBuAAsACoAX5iZueM+SH3He5e5+51JSUlkw6bjxYURyY1LiIyUzIp9CiwMGW5jMSReKrbgGZP6AbeARZnJ2J+W9dQSaSwYMRYpLCAdQ2VOUokIrNVJoW+D1hkZhVm9hngRmDXqG3eA1YCmNmfAJXAkWwGzVeNtaVsvm4JpcURDCgtjrD5uiW6ICoiZ9yEd7m4+4CZ3Q20AgXATnc/ZGZ3Jtc/CvwAeNzMOkmcornf3T+Ywdx5pbG2VAUuIjmX0Xzo7v4c8NyosUdTvu8BLs9uNBERmQx9UlREJCRU6CIiIaFCFxEJCRW6iEhIqNBFREJChS4iEhIqdBGRkFChi4iEhApdRCQkVOgiIiGhQhcRCQkVuohISKjQRURCQoUuIhISKnQRkZBQoYuIhIQKXUQkJFToIiIhoUIXEQkJFbqISEio0FN1NMFDVfBAceK1oynXiUREMjYn1wHyRkcT7L4X+uOJ5RPHEssA1Wtyl0tEJEM6Qh+yZ9MnZT6kP54YFxEJABX6kBPRyY2LiOQZFfqQuWWTGxcRyTMq9CErN0JhZORYYSQxLiISACr0IdVrYPU2mLsQsMTr6m26ICoigaG7XFJVr1GBi0hg6QhdRCQkVOgiIiGRUaGb2RVm1mVm3Wa2fpxtVpjZATM7ZGYvZTdm9rW0x6jfspeK9c9Sv2UvLe2xXEcSEZmWCc+hm1kBsB1YBUSBfWa2y90Pp2xTDDwCXOHu75nZH89U4GxoaY+xobmTeP8gALG+OBuaOwForC3NZTQRkSnL5Aj9EqDb3Y+4+8fAU8C1o7b5CtDs7u8BuPv72Y2ZXVtbu4bLfEi8f5CtrV05SiQiMn2ZFHopcCxlOZocS3UBcK6ZvWhm+83s6+neyMzWmlmbmbX19vZOLXEW9PTFJzUuIhIEmRS6pRnzUctzgD8DrgYagL8yswvG/JD7Dnevc/e6kpKSSYfNlgXFkUmNi4gEQSaFHgUWpiyXAT1ptnne3f/V3T8A/hG4KDsRs29dQyWRwoIRY5HCAtY1VOYokYjI9GVS6PuARWZWYWafAW4Edo3a5u+B/2hmc8zsD4BLgTeyGzV7GmtL2XzdEkqLIxhQWhxh83VLdEFURAJtwrtc3H3AzO4GWoECYKe7HzKzO5PrH3X3N8zseaADOA085u4HZzL4dDXWlqrARSRUzH306fAzo66uztva2nKybxGRoDKz/e5el26dPikqIhISKnQRkZBQoYuIhIQKXUQkJFToIiIhoUIXEQkJFbqISEio0EVEQkKFLiISEip0EZGQUKGLiITE7Cn0jiZ4qAoeKE68djTlOpGISFZNONtiKHQ0we57oT/5RKITxxLLANVrcpdLRCSLZscR+p5Nn5T5kP54YlxEJCRmR6GfiE5uXEQkgGZHoc8tm9y4iEgAzY5CX7kRCkc9ALowkhgXEQmJ2VHo1Wtg9TaYuxCwxOvqbbogKiKhMjvucoFEeavARSTEZscRuojILKBCFxEJCRW6iEhIqNBFREJChS4iEhIqdBGRkFChi4iEhApdRCQkVOgiIiGhQhcRCQkVuohISKjQRURCIqNCN7MrzKzLzLrNbP2nbHexmQ2a2fXZizh5Le0x6rfspWL9s9Rv2UtLeyyXcUREzogJZ1s0swJgO7AKiAL7zGyXux9Os91fA60zETRTLe0xNjR3Eu8fBCDWF2dDcycAjbWluYwmIjKjMjlCvwTodvcj7v4x8BRwbZrt7gH+Fng/i/kmbWtr13CZD4n3D7K1tStHiUREzoxMCr0UOJayHE2ODTOzUuAvgUc/7Y3MbK2ZtZlZW29v72SzZqSnLz6pcRGRsMik0C3NmI9afhi4390H02z7yQ+573D3OnevKykpyTTjpCwojkxqXEQkLDIp9CiwMGW5DOgZtU0d8JSZHQWuBx4xs8asJJykdQ2VRAoLRoxFCgtY11CZizgiImdMJo+g2wcsMrMKIAbcCHwldQN3rxj63sweB55x95Ys5szY0IXPra1d9PTFWVAcYV1DpS6IikjoTVjo7j5gZneTuHulANjp7ofM7M7k+k89b54LjbWlKnARmXUyeki0uz8HPDdqLG2Ru/ut048lIiKTpU+KioiEhApdRCQkVOgiIiGhQhcRCQkVuohISKjQRURCQoUuIhISKnQRkZBQoYuIhIQKXUQkJFToIiIhoUIXEQkJFbqISEio0EVEQkKFLiISEip0EZGQUKGLiISECl1EJCRU6CIiIaFCFxEJCRW6iEhIqNBFREJChS4iEhIqdBGRkFChi4iEhApdRCQkVOgiIiGhQhcRCQkVuohISKjQRURCIqNCN7MrzKzLzLrNbH2a9V81s47k1z+Z2UXZj5peS3uM+i17qVj/LPVb9tLSHjtTuxYRyStzJtrAzAqA7cAqIArsM7Nd7n44ZbN3gP/s7v9iZlcCO4BLZyJwqpb2GBuaO4n3DwIQ64uzobkTgMba0pnevYhIXsnkCP0SoNvdj7j7x8BTwLWpG7j7P7n7vyQXXwXKshszva2tXcNlPiTeP8jW1q4zsXsRkbySSaGXAsdSlqPJsfHcDvyvdCvMbK2ZtZlZW29vb+Ypx9HTF5/UuIhImGVS6JZmzNNuaPbnJAr9/nTr3X2Hu9e5e11JSUnmKcexoDgyqXERkTDLpNCjwMKU5TKgZ/RGZlYNPAZc6+7HsxPv061rqCRSWDBiLFJYwLqGyjOxexGRvDLhRVFgH7DIzCqAGHAj8JXUDczs3wPNwNfc/a2spxzH0IXPra1d9PTFWVAcYV1DpS6IisisNGGhu/uAmd0NtAIFwE53P2RmdybXPwpsBOYBj5gZwIC7181c7E801paqwEVEAHNPezp8xtXV1XlbW9v03qSjCfZsghNRmFsGKzdC9ZrsBBQRyUNmtn+8A+ZMTrnkp44m2H0v9CfvaDlxLLEMKnURmZWC+9H/PZs+KfMh/fHEuIjILBTcQj8Rndy4iEjIBbfQ547zYdTxxkVEQi64hb5yIxSO+gBRYSQxLiIyCwW30KvXwOptMHchYInX1dt0QVREZq3g3uUCifJWgYuIAEE+QhcRkRFU6CIiIaFCFxEJCRW6iEhIBLfQO5rgoSp4oDjx2tGU60QiIjkVzLtcNI+LiMgYwTxC1zwuIiJjBLPQNY+LiMgYwSx0zeMiIjJGMAtd87iIiIwRzELXPC4iImME8y4X0DwuIiKjBPMIXURExlChi4iEhApdRCQkVOgiIiERvELXHC4iImkF6y4XzeEiIjKuYB2haw4XEZFxBavQNYeLiMi4glXomsNFRGRcwSp0zeEiIjKuYBW65nARERlXsO5yAc3hIiIyjoyO0M3sCjPrMrNuM1ufZr2Z2bbk+g4zW5r9qNDSHqN+y14q1j9L/Za9tLTHZmI3IiKBNOERupkVANuBVUAU2Gdmu9z9cMpmVwKLkl+XAj9NvmZNS3uMDc2dxPsHAYj1xdnQ3AlAY21pNnclIhJImRyhXwJ0u/sRd/8YeAq4dtQ21wI/94RXgWIzOy+bQbe2dg2X+ZB4/yBbW7uyuRsRkcDKpNBLgWMpy9Hk2GS3wczWmlmbmbX19vZOKmhPX3xS4yIis00mhW5pxnwK2+DuO9y9zt3rSkpKMsk3bEFxZFLjIiKzTSaFHgUWpiyXAT1T2GZa1jVUEiksGDEWKSxgXUNlNncjIhJYmRT6PmCRmVWY2WeAG4Fdo7bZBXw9ebfLMuCEu/82m0Eba0vZfN0SSosjGFBaHGHzdUt0QVREJGnCu1zcfcDM7gZagQJgp7sfMrM7k+sfBZ4DrgK6gZPAbTMRtrG2VAUuIjKOjD5Y5O7PkSjt1LFHU7534K7sRhMRkckI1kf/RURkXCp0EZGQUKGLiISECl1EJCQscT0zBzs26wXeneKPzwc+yGKcM035cyfI2SHY+YOcHfIn//nunvaTmTkr9OkwszZ3r8t1jqlS/twJcnYIdv4gZ4dg5NcpFxGRkFChi4iERFALfUeuA0yT8udOkLNDsPMHOTsEIH8gz6GLiMhYQT1CFxGRUVToIiIhEbhCn+iB1fnGzHaa2ftmdjBl7I/M7B/M7J+Tr+fmMuN4zGyhmb1gZm+Y2SEz+3ZyPO/zm1mRmf0fM3s9mf2/JcfzPnsqMysws3Yzeya5HJj8ZnbUzDrN7ICZtSXHApHfzIrN7GkzezP55/+yIGQPVKGnPLD6SuBPgZvM7E9zm2pCjwNXjBpbD+xx90XAnuRyPhoAvuPuFwLLgLuSv+8g5P834AvufhFQA1yRnKs/CNlTfRt4I2U5aPn/3N1rUu7fDkr+/w487+6LgYtI/DvI/+zuHpgv4DKgNWV5A7Ah17kyyF0OHExZ7gLOS35/HtCV64wZ/nP8PbAqaPmBPwBeAy4NUnYST/7aA3wBeCZof3aAo8D8UWN5nx84B3iH5E0jQcoeqCN0MnwYdQD8iSef6JR8/eMc55mQmZUDtcD/JiD5k6crDgDvA//g7oHJnvQw8F3gdMpYkPI78Esz229ma5NjQcj/WaAX+B/J012PmdlZBCB70Ao9o4dRS3aZ2R8Cfwv8F3f/f7nOkyl3H3T3GhJHupeYWVWuM2XKzK4B3nf3/bnOMg317r6UxCnSu8zsP+U6UIbmAEuBn7p7LfCv5OPplTSCVugz/jDqM+T/mtl5AMnX93OcZ1xmVkiizP/G3ZuTw4HJD+DufcCLJK5lBCV7PfAXZnYUeAr4gpn9T4KTH3fvSb6+D/wdcAnByB8Fosm/0QE8TaLg8z570Ao9kwdWB8Eu4Jbk97eQODedd8zMgJ8Bb7j7j1NW5X1+Mysxs+Lk9xHgi8CbBCA7gLtvcPcydy8n8ed8r7vfTEDym9lZZnb20PfA5cBBApDf3X8HHDOzyuTQSuAwAcie85P4U7hgcRXwFvA28L1c58kg75PAb4F+Ev/nvx2YR+Ji1z8nX/8o1znHyb6cxCmtDuBA8uuqIOQHqoH2ZPaDwMbkeN5nT/PPsoJPLooGIj+J89CvJ78ODf23GqD8NUBb8s9PC3BuELLro/8iIiERtFMuIiIyDhW6iEhIqNBFREJChS4iEhIqdBGRkFChi4iEhApdRCQk/j+kOk+DU079wQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "brks = tensor(0,1,2,4,8,64).float()\n",
    "ys = tensor(range_of(brks)).float()\n",
    "ys /= ys[-1].item()\n",
    "pts = tensor(0.2,0.5,0.8,3,5,63)\n",
    "\n",
    "preds = pts.interp_1d(brks, ys)\n",
    "test_close(preds.numpy(), np.interp(pts.numpy(), brks.numpy(), ys.numpy()))\n",
    "\n",
    "plt.scatter(brks,ys)\n",
    "plt.scatter(pts,preds)\n",
    "plt.legend(['breaks','preds']);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def pca(x:Tensor, k=2):\n",
    "    \"Compute PCA of `x` with `k` dimensions.\"\n",
    "    x = x-torch.mean(x,0)\n",
    "    U,S,V = torch.svd(x.t())\n",
    "    return torch.mm(x,U[:,:k])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def logit(x):\n",
    "    \"Logit of `x`, clamped to avoid inf.\"\n",
    "    x = x.clamp(1e-7, 1-1e-7)\n",
    "    return -(1/x-1).log()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def num_distrib():\n",
    "    \"Return the number of processes in distributed training (if applicable).\"\n",
    "    return int(os.environ.get('WORLD_SIZE', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def rank_distrib():\n",
    "    \"Return the distributed rank of this process (if applicable).\"\n",
    "    return int(os.environ.get('RANK', 0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def distrib_barrier():\n",
    "    \"Place a synchronization barrier in distributed training so that ALL sub-processes in the pytorch process group must arrive here before proceeding.\"\n",
    "    if num_distrib() > 1 and torch.distributed.is_initialized(): torch.distributed.barrier()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "# Saving arrays requires pytables - optional dependency\n",
    "try: import tables\n",
    "except: pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def _comp_filter(lib='lz4',lvl=3): return tables.Filters(complib=f'blosc:{lib}', complevel=lvl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def save_array(p:Path, o, complib='lz4', lvl=3):\n",
    "    \"Save numpy array to a compressed `pytables` file, using compression level `lvl`\"\n",
    "    if isinstance(o,Tensor): o = to_np(o)\n",
    "    with tables.open_file(p, mode='w', filters=_comp_filter(lib=complib,lvl=lvl)) as f: f.create_carray('/', 'data', obj=o)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compression lib can be any of: blosclz, lz4, lz4hc, snappy, zlib or zstd."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "@patch\n",
    "def load_array(p:Path):\n",
    "    \"Save numpy array to a `pytables` file\"\n",
    "    with tables.open_file(p, 'r') as f: return f.root.data.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Save numpy array to a `pytables` file'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inspect.getdoc(load_array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'(p: pathlib.Path)'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "str(inspect.signature(load_array))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def base_doc(elt):\n",
    "    \"Print a base documentation of `elt`\"\n",
    "    name = getattr(elt, '__qualname__', getattr(elt, '__name__', ''))\n",
    "    print(f'{name}{inspect.signature(elt)}\\n{inspect.getdoc(elt)}\\n')\n",
    "    print('To get a prettier result with hyperlinks to source code and documentation, install nbdev: pip install nbdev')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def doc(elt):\n",
    "    \"Try to use doc form nbdev and fall back to `base_doc`\"\n",
    "    try:\n",
    "        from nbdev.showdoc import doc\n",
    "        doc(elt)\n",
    "    except: base_doc(elt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def nested_reorder(t, idxs):\n",
    "    \"Reorder all tensors in `t` using `idxs`\"\n",
    "    if isinstance(t, (Tensor,L)): return t[idxs]\n",
    "    elif is_listy(t): return type(t)(nested_reorder(t_, idxs) for t_ in t)\n",
    "    if t is None: return t\n",
    "    raise TypeError(f\"Expected tensor, tuple, list or L but got {type(t)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = tensor([0,1,2,3,4,5])\n",
    "idxs = tensor([2,5,1,0,3,4])\n",
    "test_eq_type(nested_reorder(([x], x), idxs), ([idxs], idxs))\n",
    "\n",
    "y = L(0,1,2,3,4,5)\n",
    "z = L(i.item() for i in idxs)\n",
    "test_eq_type(nested_reorder((y, x), idxs), (z,idxs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Image helpers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def make_cross_image(bw=True):\n",
    "    \"Create a tensor containing a cross image, either `bw` (True) or color\"\n",
    "    if bw:\n",
    "        im = torch.zeros(5,5)\n",
    "        im[2,:] = 1.\n",
    "        im[:,2] = 1.\n",
    "    else:\n",
    "        im = torch.zeros(3,5,5)\n",
    "        im[0,2,:] = 1.\n",
    "        im[1,:,2] = 1.\n",
    "    return im"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(), cmap=\"Greys\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(make_cross_image(False).permute(1,2,0));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def show_image_batch(b, show=show_titled_image, items=9, cols=3, figsize=None, **kwargs):\n",
    "    \"Display batch `b` in a grid of size `items` with `cols` width\"\n",
    "    if items<cols: cols=items\n",
    "    rows = (items+cols-1) // cols\n",
    "    if figsize is None: figsize = (cols*3, rows*3)\n",
    "    fig,axs = plt.subplots(rows, cols, figsize=figsize)\n",
    "    for *o,ax in zip(*to_cpu(b), axs.flatten()): show(o, ax=ax, **kwargs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_image_batch(([Image.open(TEST_IMAGE_BW),Image.open(TEST_IMAGE)],['bw','color']), items=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model init"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def requires_grad(m):\n",
    "    \"Check if the first parameter of `m` requires grad or not\"\n",
    "    ps = list(m.parameters())\n",
    "    return ps[0].requires_grad if len(ps)>0 else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "assert requires_grad(tst)\n",
    "for p in tst.parameters(): p.requires_grad_(False)\n",
    "assert not requires_grad(tst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def init_default(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize `m` weights with `func` and set `bias` to 0.\"\n",
    "    if func:\n",
    "        if hasattr(m, 'weight'): func(m.weight)\n",
    "        if hasattr(m, 'bias') and hasattr(m.bias, 'data'): m.bias.data.fill_(0.)\n",
    "    return m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "tst = init_default(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def cond_init(m, func):\n",
    "    \"Apply `init_default` to `m` unless it's a batchnorm module\"\n",
    "    if (not isinstance(m, norm_types)) and requires_grad(m): init_default(m, func)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Linear(4,5)\n",
    "tst.weight.data.uniform_(-1,1)\n",
    "tst.bias.data.uniform_(-1,1)\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, torch.ones(5,4))\n",
    "test_eq(tst.bias, torch.zeros(5))\n",
    "\n",
    "tst = nn.BatchNorm2d(5)\n",
    "init = [tst.weight.clone(), tst.bias.clone()]\n",
    "cond_init(tst, func = lambda x: x.data.fill_(1.))\n",
    "test_eq(tst.weight, init[0])\n",
    "test_eq(tst.bias, init[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_leaf(m, f):\n",
    "    \"Apply `f` to children of `m`.\"\n",
    "    c = m.children()\n",
    "    if isinstance(m, nn.Module): f(m)\n",
    "    for l in c: apply_leaf(l,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.Linear(4,5)))\n",
    "apply_leaf(tst, partial(init_default, func=lambda x: x.data.fill_(1.)))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], *tst[1]]: test_eq(l.bias,   torch.zeros(5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def apply_init(m, func=nn.init.kaiming_normal_):\n",
    "    \"Initialize all non-batchnorm layers of `m` with `func`.\"\n",
    "    apply_leaf(m, partial(cond_init, func=func))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tst = nn.Sequential(nn.Linear(4,5), nn.Sequential(nn.Linear(4,5), nn.BatchNorm1d(5)))\n",
    "init = [tst[1][1].weight.clone(), tst[1][1].bias.clone()]\n",
    "apply_init(tst, func=lambda x: x.data.fill_(1.))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.weight, torch.ones(5,4))\n",
    "for l in [tst[0], tst[1][0]]: test_eq(l.bias,   torch.zeros(5))\n",
    "test_eq(tst[1][1].weight, init[0])\n",
    "test_eq(tst[1][1].bias,   init[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## autograd jit functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_use_ctx(f):\n",
    "    \"Decorator: create jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    sf = torch.jit.script(f)\n",
    "    def _f(ctx, *args, **kwargs): return sf(*args, *ctx.saved_variables, **kwargs)\n",
    "    return update_wrapper(_f,f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_save_ctx(static, *argidx):\n",
    "    \"Decorator: create jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    def _dec(f):\n",
    "        sf = torch.jit.script(f)\n",
    "        def _f(ctx, *args, **kwargs):\n",
    "            if argidx:\n",
    "                save = [args[o] for o in argidx]\n",
    "                ctx.save_for_backward(*save)\n",
    "            if not argidx: args = [ctx]+args\n",
    "            return sf(*args, **kwargs)\n",
    "        if static: _f = staticmethod(_f)\n",
    "        return update_wrapper(_f,f)\n",
    "    return _dec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_fwd(*argidx):\n",
    "    \"Decorator: create static jit script and save args with indices `argidx` using `ctx.save_for_backward`\"\n",
    "    return script_save_ctx(True, *argidx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def script_bwd(f):\n",
    "    \"Decorator: create static jit script and pass everything in `ctx.saved_variables to `f`, after `*args`\"\n",
    "    return staticmethod(script_use_ctx(f))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "def grad_module(cls):\n",
    "    \"Decorator: convert `cls` into an autograd function\"\n",
    "    class _c(nn.Module):\n",
    "        def forward(self, *args, **kwargs): return cls.apply(*args, **kwargs)\n",
    "    return _c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Export -"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Converted 00_torch_core.ipynb.\n",
      "Converted 01_layers.ipynb.\n",
      "Converted 02_data.load.ipynb.\n",
      "Converted 03_data.core.ipynb.\n",
      "Converted 04_data.external.ipynb.\n",
      "Converted 05_data.transforms.ipynb.\n",
      "Converted 06_data.block.ipynb.\n",
      "Converted 07_vision.core.ipynb.\n",
      "Converted 08_vision.data.ipynb.\n",
      "Converted 09_vision.augment.ipynb.\n",
      "Converted 09b_vision.utils.ipynb.\n",
      "Converted 09c_vision.widgets.ipynb.\n",
      "Converted 10_tutorial.pets.ipynb.\n",
      "Converted 11_vision.models.xresnet.ipynb.\n",
      "Converted 12_optimizer.ipynb.\n",
      "Converted 13_callback.core.ipynb.\n",
      "Converted 13a_learner.ipynb.\n",
      "Converted 13b_metrics.ipynb.\n",
      "Converted 14_callback.schedule.ipynb.\n",
      "Converted 14a_callback.data.ipynb.\n",
      "Converted 15_callback.hook.ipynb.\n",
      "Converted 15a_vision.models.unet.ipynb.\n",
      "Converted 16_callback.progress.ipynb.\n",
      "Converted 17_callback.tracker.ipynb.\n",
      "Converted 18_callback.fp16.ipynb.\n",
      "Converted 18a_callback.training.ipynb.\n",
      "Converted 19_callback.mixup.ipynb.\n",
      "Converted 20_interpret.ipynb.\n",
      "Converted 20a_distributed.ipynb.\n",
      "Converted 21_vision.learner.ipynb.\n",
      "Converted 22_tutorial.imagenette.ipynb.\n",
      "Converted 23_tutorial.vision.ipynb.\n",
      "Converted 24_tutorial.siamese.ipynb.\n",
      "Converted 24_vision.gan.ipynb.\n",
      "Converted 30_text.core.ipynb.\n",
      "Converted 31_text.data.ipynb.\n",
      "Converted 32_text.models.awdlstm.ipynb.\n",
      "Converted 33_text.models.core.ipynb.\n",
      "Converted 34_callback.rnn.ipynb.\n",
      "Converted 35_tutorial.wikitext.ipynb.\n",
      "Converted 36_text.models.qrnn.ipynb.\n",
      "Converted 37_text.learner.ipynb.\n",
      "Converted 38_tutorial.text.ipynb.\n",
      "Converted 39_tutorial.transformers.ipynb.\n",
      "Converted 40_tabular.core.ipynb.\n",
      "Converted 41_tabular.data.ipynb.\n",
      "Converted 42_tabular.model.ipynb.\n",
      "Converted 43_tabular.learner.ipynb.\n",
      "Converted 44_tutorial.tabular.ipynb.\n",
      "Converted 45_collab.ipynb.\n",
      "Converted 46_tutorial.collab.ipynb.\n",
      "Converted 50_tutorial.datablock.ipynb.\n",
      "Converted 60_medical.imaging.ipynb.\n",
      "Converted 61_tutorial.medical_imaging.ipynb.\n",
      "Converted 65_medical.text.ipynb.\n",
      "Converted 70_callback.wandb.ipynb.\n",
      "Converted 71_callback.tensorboard.ipynb.\n",
      "Converted 72_callback.neptune.ipynb.\n",
      "Converted 73_callback.captum.ipynb.\n",
      "Converted 74_callback.cutmix.ipynb.\n",
      "Converted 97_test_utils.ipynb.\n",
      "Converted 99_pytorch_doc.ipynb.\n",
      "Converted index.ipynb.\n",
      "Converted tutorial.ipynb.\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "from nbdev.export import notebook2script\n",
    "notebook2script()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "split_at_heading": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
